1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, serde::Serialize)]
14pub struct NeighborTable {
15 pub ext_address: Option<u64>,
16 pub age: Option<u32>,
17 pub rloc16: Option<u16>,
18 pub link_frame_counter: Option<u32>,
19 pub mle_frame_counter: Option<u32>,
20 pub lqi: Option<u8>,
21 pub average_rssi: Option<i8>,
22 pub last_rssi: Option<i8>,
23 pub frame_error_rate: Option<u8>,
24 pub message_error_rate: Option<u8>,
25 pub rx_on_when_idle: Option<bool>,
26 pub full_thread_device: Option<bool>,
27 pub full_network_data: Option<bool>,
28 pub is_child: Option<bool>,
29}
30
31#[derive(Debug, serde::Serialize)]
32pub struct OperationalDatasetComponents {
33 pub active_timestamp_present: Option<bool>,
34 pub pending_timestamp_present: Option<bool>,
35 pub master_key_present: Option<bool>,
36 pub network_name_present: Option<bool>,
37 pub extended_pan_id_present: Option<bool>,
38 pub mesh_local_prefix_present: Option<bool>,
39 pub delay_present: Option<bool>,
40 pub pan_id_present: Option<bool>,
41 pub channel_present: Option<bool>,
42 pub pskc_present: Option<bool>,
43 pub security_policy_present: Option<bool>,
44 pub channel_mask_present: Option<bool>,
45}
46
47#[derive(Debug, serde::Serialize)]
48pub struct RouteTable {
49 pub ext_address: Option<u64>,
50 pub rloc16: Option<u16>,
51 pub router_id: Option<u8>,
52 pub next_hop: Option<u8>,
53 pub path_cost: Option<u8>,
54 pub lqi_in: Option<u8>,
55 pub lqi_out: Option<u8>,
56 pub age: Option<u8>,
57 pub allocated: Option<bool>,
58 pub link_established: Option<bool>,
59}
60
61#[derive(Debug, serde::Serialize)]
62pub struct SecurityPolicy {
63 pub rotation_time: Option<u16>,
64 pub flags: Option<u16>,
65}
66
67pub fn decode_channel(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
73 if let tlv::TlvItemValue::Int(v) = inp {
74 Ok(Some(*v as u16))
75 } else {
76 Ok(None)
77 }
78}
79
80pub fn decode_routing_role(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
82 if let tlv::TlvItemValue::Int(v) = inp {
83 Ok(Some(*v as u8))
84 } else {
85 Ok(None)
86 }
87}
88
89pub fn decode_network_name(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<String>> {
91 if let tlv::TlvItemValue::String(v) = inp {
92 Ok(Some(v.clone()))
93 } else {
94 Ok(None)
95 }
96}
97
98pub fn decode_pan_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
100 if let tlv::TlvItemValue::Int(v) = inp {
101 Ok(Some(*v as u16))
102 } else {
103 Ok(None)
104 }
105}
106
107pub fn decode_extended_pan_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
109 if let tlv::TlvItemValue::Int(v) = inp {
110 Ok(Some(*v))
111 } else {
112 Ok(None)
113 }
114}
115
116pub fn decode_mesh_local_prefix(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
118 if let tlv::TlvItemValue::Int(v) = inp {
119 Ok(Some(*v as u8))
120 } else {
121 Ok(None)
122 }
123}
124
125pub fn decode_overrun_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u64> {
127 if let tlv::TlvItemValue::Int(v) = inp {
128 Ok(*v)
129 } else {
130 Err(anyhow::anyhow!("Expected Integer"))
131 }
132}
133
134pub fn decode_neighbor_table(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<NeighborTable>> {
136 let mut res = Vec::new();
137 if let tlv::TlvItemValue::List(v) = inp {
138 for item in v {
139 res.push(NeighborTable {
140 ext_address: item.get_int(&[0]),
141 age: item.get_int(&[1]).map(|v| v as u32),
142 rloc16: item.get_int(&[2]).map(|v| v as u16),
143 link_frame_counter: item.get_int(&[3]).map(|v| v as u32),
144 mle_frame_counter: item.get_int(&[4]).map(|v| v as u32),
145 lqi: item.get_int(&[5]).map(|v| v as u8),
146 average_rssi: item.get_int(&[6]).map(|v| v as i8),
147 last_rssi: item.get_int(&[7]).map(|v| v as i8),
148 frame_error_rate: item.get_int(&[8]).map(|v| v as u8),
149 message_error_rate: item.get_int(&[9]).map(|v| v as u8),
150 rx_on_when_idle: item.get_bool(&[10]),
151 full_thread_device: item.get_bool(&[11]),
152 full_network_data: item.get_bool(&[12]),
153 is_child: item.get_bool(&[13]),
154 });
155 }
156 }
157 Ok(res)
158}
159
160pub fn decode_route_table(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<RouteTable>> {
162 let mut res = Vec::new();
163 if let tlv::TlvItemValue::List(v) = inp {
164 for item in v {
165 res.push(RouteTable {
166 ext_address: item.get_int(&[0]),
167 rloc16: item.get_int(&[1]).map(|v| v as u16),
168 router_id: item.get_int(&[2]).map(|v| v as u8),
169 next_hop: item.get_int(&[3]).map(|v| v as u8),
170 path_cost: item.get_int(&[4]).map(|v| v as u8),
171 lqi_in: item.get_int(&[5]).map(|v| v as u8),
172 lqi_out: item.get_int(&[6]).map(|v| v as u8),
173 age: item.get_int(&[7]).map(|v| v as u8),
174 allocated: item.get_bool(&[8]),
175 link_established: item.get_bool(&[9]),
176 });
177 }
178 }
179 Ok(res)
180}
181
182pub fn decode_partition_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
184 if let tlv::TlvItemValue::Int(v) = inp {
185 Ok(Some(*v as u32))
186 } else {
187 Ok(None)
188 }
189}
190
191pub fn decode_weighting(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
193 if let tlv::TlvItemValue::Int(v) = inp {
194 Ok(Some(*v as u16))
195 } else {
196 Ok(None)
197 }
198}
199
200pub fn decode_data_version(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
202 if let tlv::TlvItemValue::Int(v) = inp {
203 Ok(Some(*v as u16))
204 } else {
205 Ok(None)
206 }
207}
208
209pub fn decode_stable_data_version(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
211 if let tlv::TlvItemValue::Int(v) = inp {
212 Ok(Some(*v as u16))
213 } else {
214 Ok(None)
215 }
216}
217
218pub fn decode_leader_router_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
220 if let tlv::TlvItemValue::Int(v) = inp {
221 Ok(Some(*v as u8))
222 } else {
223 Ok(None)
224 }
225}
226
227pub fn decode_detached_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
229 if let tlv::TlvItemValue::Int(v) = inp {
230 Ok(*v as u16)
231 } else {
232 Err(anyhow::anyhow!("Expected Integer"))
233 }
234}
235
236pub fn decode_child_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
238 if let tlv::TlvItemValue::Int(v) = inp {
239 Ok(*v as u16)
240 } else {
241 Err(anyhow::anyhow!("Expected Integer"))
242 }
243}
244
245pub fn decode_router_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
247 if let tlv::TlvItemValue::Int(v) = inp {
248 Ok(*v as u16)
249 } else {
250 Err(anyhow::anyhow!("Expected Integer"))
251 }
252}
253
254pub fn decode_leader_role_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
256 if let tlv::TlvItemValue::Int(v) = inp {
257 Ok(*v as u16)
258 } else {
259 Err(anyhow::anyhow!("Expected Integer"))
260 }
261}
262
263pub fn decode_attach_attempt_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
265 if let tlv::TlvItemValue::Int(v) = inp {
266 Ok(*v as u16)
267 } else {
268 Err(anyhow::anyhow!("Expected Integer"))
269 }
270}
271
272pub fn decode_partition_id_change_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
274 if let tlv::TlvItemValue::Int(v) = inp {
275 Ok(*v as u16)
276 } else {
277 Err(anyhow::anyhow!("Expected Integer"))
278 }
279}
280
281pub fn decode_better_partition_attach_attempt_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
283 if let tlv::TlvItemValue::Int(v) = inp {
284 Ok(*v as u16)
285 } else {
286 Err(anyhow::anyhow!("Expected Integer"))
287 }
288}
289
290pub fn decode_parent_change_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
292 if let tlv::TlvItemValue::Int(v) = inp {
293 Ok(*v as u16)
294 } else {
295 Err(anyhow::anyhow!("Expected Integer"))
296 }
297}
298
299pub fn decode_tx_total_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
301 if let tlv::TlvItemValue::Int(v) = inp {
302 Ok(*v as u32)
303 } else {
304 Err(anyhow::anyhow!("Expected Integer"))
305 }
306}
307
308pub fn decode_tx_unicast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
310 if let tlv::TlvItemValue::Int(v) = inp {
311 Ok(*v as u32)
312 } else {
313 Err(anyhow::anyhow!("Expected Integer"))
314 }
315}
316
317pub fn decode_tx_broadcast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
319 if let tlv::TlvItemValue::Int(v) = inp {
320 Ok(*v as u32)
321 } else {
322 Err(anyhow::anyhow!("Expected Integer"))
323 }
324}
325
326pub fn decode_tx_ack_requested_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
328 if let tlv::TlvItemValue::Int(v) = inp {
329 Ok(*v as u32)
330 } else {
331 Err(anyhow::anyhow!("Expected Integer"))
332 }
333}
334
335pub fn decode_tx_acked_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
337 if let tlv::TlvItemValue::Int(v) = inp {
338 Ok(*v as u32)
339 } else {
340 Err(anyhow::anyhow!("Expected Integer"))
341 }
342}
343
344pub fn decode_tx_no_ack_requested_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
346 if let tlv::TlvItemValue::Int(v) = inp {
347 Ok(*v as u32)
348 } else {
349 Err(anyhow::anyhow!("Expected Integer"))
350 }
351}
352
353pub fn decode_tx_data_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
355 if let tlv::TlvItemValue::Int(v) = inp {
356 Ok(*v as u32)
357 } else {
358 Err(anyhow::anyhow!("Expected Integer"))
359 }
360}
361
362pub fn decode_tx_data_poll_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
364 if let tlv::TlvItemValue::Int(v) = inp {
365 Ok(*v as u32)
366 } else {
367 Err(anyhow::anyhow!("Expected Integer"))
368 }
369}
370
371pub fn decode_tx_beacon_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
373 if let tlv::TlvItemValue::Int(v) = inp {
374 Ok(*v as u32)
375 } else {
376 Err(anyhow::anyhow!("Expected Integer"))
377 }
378}
379
380pub fn decode_tx_beacon_request_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
382 if let tlv::TlvItemValue::Int(v) = inp {
383 Ok(*v as u32)
384 } else {
385 Err(anyhow::anyhow!("Expected Integer"))
386 }
387}
388
389pub fn decode_tx_other_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
391 if let tlv::TlvItemValue::Int(v) = inp {
392 Ok(*v as u32)
393 } else {
394 Err(anyhow::anyhow!("Expected Integer"))
395 }
396}
397
398pub fn decode_tx_retry_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
400 if let tlv::TlvItemValue::Int(v) = inp {
401 Ok(*v as u32)
402 } else {
403 Err(anyhow::anyhow!("Expected Integer"))
404 }
405}
406
407pub fn decode_tx_direct_max_retry_expiry_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
409 if let tlv::TlvItemValue::Int(v) = inp {
410 Ok(*v as u32)
411 } else {
412 Err(anyhow::anyhow!("Expected Integer"))
413 }
414}
415
416pub fn decode_tx_indirect_max_retry_expiry_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
418 if let tlv::TlvItemValue::Int(v) = inp {
419 Ok(*v as u32)
420 } else {
421 Err(anyhow::anyhow!("Expected Integer"))
422 }
423}
424
425pub fn decode_tx_err_cca_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
427 if let tlv::TlvItemValue::Int(v) = inp {
428 Ok(*v as u32)
429 } else {
430 Err(anyhow::anyhow!("Expected Integer"))
431 }
432}
433
434pub fn decode_tx_err_abort_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
436 if let tlv::TlvItemValue::Int(v) = inp {
437 Ok(*v as u32)
438 } else {
439 Err(anyhow::anyhow!("Expected Integer"))
440 }
441}
442
443pub fn decode_tx_err_busy_channel_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
445 if let tlv::TlvItemValue::Int(v) = inp {
446 Ok(*v as u32)
447 } else {
448 Err(anyhow::anyhow!("Expected Integer"))
449 }
450}
451
452pub fn decode_rx_total_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
454 if let tlv::TlvItemValue::Int(v) = inp {
455 Ok(*v as u32)
456 } else {
457 Err(anyhow::anyhow!("Expected Integer"))
458 }
459}
460
461pub fn decode_rx_unicast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
463 if let tlv::TlvItemValue::Int(v) = inp {
464 Ok(*v as u32)
465 } else {
466 Err(anyhow::anyhow!("Expected Integer"))
467 }
468}
469
470pub fn decode_rx_broadcast_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
472 if let tlv::TlvItemValue::Int(v) = inp {
473 Ok(*v as u32)
474 } else {
475 Err(anyhow::anyhow!("Expected Integer"))
476 }
477}
478
479pub fn decode_rx_data_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
481 if let tlv::TlvItemValue::Int(v) = inp {
482 Ok(*v as u32)
483 } else {
484 Err(anyhow::anyhow!("Expected Integer"))
485 }
486}
487
488pub fn decode_rx_data_poll_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
490 if let tlv::TlvItemValue::Int(v) = inp {
491 Ok(*v as u32)
492 } else {
493 Err(anyhow::anyhow!("Expected Integer"))
494 }
495}
496
497pub fn decode_rx_beacon_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
499 if let tlv::TlvItemValue::Int(v) = inp {
500 Ok(*v as u32)
501 } else {
502 Err(anyhow::anyhow!("Expected Integer"))
503 }
504}
505
506pub fn decode_rx_beacon_request_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
508 if let tlv::TlvItemValue::Int(v) = inp {
509 Ok(*v as u32)
510 } else {
511 Err(anyhow::anyhow!("Expected Integer"))
512 }
513}
514
515pub fn decode_rx_other_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
517 if let tlv::TlvItemValue::Int(v) = inp {
518 Ok(*v as u32)
519 } else {
520 Err(anyhow::anyhow!("Expected Integer"))
521 }
522}
523
524pub fn decode_rx_address_filtered_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
526 if let tlv::TlvItemValue::Int(v) = inp {
527 Ok(*v as u32)
528 } else {
529 Err(anyhow::anyhow!("Expected Integer"))
530 }
531}
532
533pub fn decode_rx_dest_addr_filtered_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
535 if let tlv::TlvItemValue::Int(v) = inp {
536 Ok(*v as u32)
537 } else {
538 Err(anyhow::anyhow!("Expected Integer"))
539 }
540}
541
542pub fn decode_rx_duplicated_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
544 if let tlv::TlvItemValue::Int(v) = inp {
545 Ok(*v as u32)
546 } else {
547 Err(anyhow::anyhow!("Expected Integer"))
548 }
549}
550
551pub fn decode_rx_err_no_frame_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
553 if let tlv::TlvItemValue::Int(v) = inp {
554 Ok(*v as u32)
555 } else {
556 Err(anyhow::anyhow!("Expected Integer"))
557 }
558}
559
560pub fn decode_rx_err_unknown_neighbor_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
562 if let tlv::TlvItemValue::Int(v) = inp {
563 Ok(*v as u32)
564 } else {
565 Err(anyhow::anyhow!("Expected Integer"))
566 }
567}
568
569pub fn decode_rx_err_invalid_src_addr_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
571 if let tlv::TlvItemValue::Int(v) = inp {
572 Ok(*v as u32)
573 } else {
574 Err(anyhow::anyhow!("Expected Integer"))
575 }
576}
577
578pub fn decode_rx_err_sec_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
580 if let tlv::TlvItemValue::Int(v) = inp {
581 Ok(*v as u32)
582 } else {
583 Err(anyhow::anyhow!("Expected Integer"))
584 }
585}
586
587pub fn decode_rx_err_fcs_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
589 if let tlv::TlvItemValue::Int(v) = inp {
590 Ok(*v as u32)
591 } else {
592 Err(anyhow::anyhow!("Expected Integer"))
593 }
594}
595
596pub fn decode_rx_err_other_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
598 if let tlv::TlvItemValue::Int(v) = inp {
599 Ok(*v as u32)
600 } else {
601 Err(anyhow::anyhow!("Expected Integer"))
602 }
603}
604
605pub fn decode_active_timestamp(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
607 if let tlv::TlvItemValue::Int(v) = inp {
608 Ok(Some(*v))
609 } else {
610 Ok(None)
611 }
612}
613
614pub fn decode_pending_timestamp(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
616 if let tlv::TlvItemValue::Int(v) = inp {
617 Ok(Some(*v))
618 } else {
619 Ok(None)
620 }
621}
622
623pub fn decode_delay(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
625 if let tlv::TlvItemValue::Int(v) = inp {
626 Ok(Some(*v as u32))
627 } else {
628 Ok(None)
629 }
630}
631
632pub fn decode_security_policy(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<SecurityPolicy>> {
634 if let tlv::TlvItemValue::List(_fields) = inp {
635 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
637 Ok(Some(SecurityPolicy {
638 rotation_time: item.get_int(&[0]).map(|v| v as u16),
639 flags: item.get_int(&[1]).map(|v| v as u16),
640 }))
641 } else {
645 Ok(None)
646 }
648}
649
650pub fn decode_channel_page0_mask(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<Vec<u8>>> {
652 if let tlv::TlvItemValue::OctetString(v) = inp {
653 Ok(Some(v.clone()))
654 } else {
655 Ok(None)
656 }
657}
658
659pub fn decode_operational_dataset_components(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<OperationalDatasetComponents>> {
661 if let tlv::TlvItemValue::List(_fields) = inp {
662 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
664 Ok(Some(OperationalDatasetComponents {
665 active_timestamp_present: item.get_bool(&[0]),
666 pending_timestamp_present: item.get_bool(&[1]),
667 master_key_present: item.get_bool(&[2]),
668 network_name_present: item.get_bool(&[3]),
669 extended_pan_id_present: item.get_bool(&[4]),
670 mesh_local_prefix_present: item.get_bool(&[5]),
671 delay_present: item.get_bool(&[6]),
672 pan_id_present: item.get_bool(&[7]),
673 channel_present: item.get_bool(&[8]),
674 pskc_present: item.get_bool(&[9]),
675 security_policy_present: item.get_bool(&[10]),
676 channel_mask_present: item.get_bool(&[11]),
677 }))
678 } else {
682 Ok(None)
683 }
685}
686
687pub fn decode_active_network_faults_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
689 let mut res = Vec::new();
690 if let tlv::TlvItemValue::List(v) = inp {
691 for item in v {
692 if let tlv::TlvItemValue::Int(i) = &item.value {
693 res.push(*i as u8);
694 }
695 }
696 }
697 Ok(res)
698}
699
700pub fn decode_ext_address(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u64>> {
702 if let tlv::TlvItemValue::Int(v) = inp {
703 Ok(Some(*v))
704 } else {
705 Ok(None)
706 }
707}
708
709pub fn decode_rloc16(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
711 if let tlv::TlvItemValue::Int(v) = inp {
712 Ok(Some(*v as u16))
713 } else {
714 Ok(None)
715 }
716}
717
718
719pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
731 if cluster_id != 0x0035 {
733 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0035, got {}\"}}", cluster_id);
734 }
735
736 match attribute_id {
737 0x0000 => {
738 match decode_channel(tlv_value) {
739 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
740 Err(e) => format!("{{\"error\": \"{}\"}}", e),
741 }
742 }
743 0x0001 => {
744 match decode_routing_role(tlv_value) {
745 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
746 Err(e) => format!("{{\"error\": \"{}\"}}", e),
747 }
748 }
749 0x0002 => {
750 match decode_network_name(tlv_value) {
751 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
752 Err(e) => format!("{{\"error\": \"{}\"}}", e),
753 }
754 }
755 0x0003 => {
756 match decode_pan_id(tlv_value) {
757 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
758 Err(e) => format!("{{\"error\": \"{}\"}}", e),
759 }
760 }
761 0x0004 => {
762 match decode_extended_pan_id(tlv_value) {
763 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
764 Err(e) => format!("{{\"error\": \"{}\"}}", e),
765 }
766 }
767 0x0005 => {
768 match decode_mesh_local_prefix(tlv_value) {
769 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
770 Err(e) => format!("{{\"error\": \"{}\"}}", e),
771 }
772 }
773 0x0006 => {
774 match decode_overrun_count(tlv_value) {
775 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
776 Err(e) => format!("{{\"error\": \"{}\"}}", e),
777 }
778 }
779 0x0007 => {
780 match decode_neighbor_table(tlv_value) {
781 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
782 Err(e) => format!("{{\"error\": \"{}\"}}", e),
783 }
784 }
785 0x0008 => {
786 match decode_route_table(tlv_value) {
787 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
788 Err(e) => format!("{{\"error\": \"{}\"}}", e),
789 }
790 }
791 0x0009 => {
792 match decode_partition_id(tlv_value) {
793 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
794 Err(e) => format!("{{\"error\": \"{}\"}}", e),
795 }
796 }
797 0x000A => {
798 match decode_weighting(tlv_value) {
799 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
800 Err(e) => format!("{{\"error\": \"{}\"}}", e),
801 }
802 }
803 0x000B => {
804 match decode_data_version(tlv_value) {
805 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
806 Err(e) => format!("{{\"error\": \"{}\"}}", e),
807 }
808 }
809 0x000C => {
810 match decode_stable_data_version(tlv_value) {
811 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
812 Err(e) => format!("{{\"error\": \"{}\"}}", e),
813 }
814 }
815 0x000D => {
816 match decode_leader_router_id(tlv_value) {
817 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
818 Err(e) => format!("{{\"error\": \"{}\"}}", e),
819 }
820 }
821 0x000E => {
822 match decode_detached_role_count(tlv_value) {
823 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
824 Err(e) => format!("{{\"error\": \"{}\"}}", e),
825 }
826 }
827 0x000F => {
828 match decode_child_role_count(tlv_value) {
829 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
830 Err(e) => format!("{{\"error\": \"{}\"}}", e),
831 }
832 }
833 0x0010 => {
834 match decode_router_role_count(tlv_value) {
835 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
836 Err(e) => format!("{{\"error\": \"{}\"}}", e),
837 }
838 }
839 0x0011 => {
840 match decode_leader_role_count(tlv_value) {
841 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
842 Err(e) => format!("{{\"error\": \"{}\"}}", e),
843 }
844 }
845 0x0012 => {
846 match decode_attach_attempt_count(tlv_value) {
847 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
848 Err(e) => format!("{{\"error\": \"{}\"}}", e),
849 }
850 }
851 0x0013 => {
852 match decode_partition_id_change_count(tlv_value) {
853 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
854 Err(e) => format!("{{\"error\": \"{}\"}}", e),
855 }
856 }
857 0x0014 => {
858 match decode_better_partition_attach_attempt_count(tlv_value) {
859 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
860 Err(e) => format!("{{\"error\": \"{}\"}}", e),
861 }
862 }
863 0x0015 => {
864 match decode_parent_change_count(tlv_value) {
865 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
866 Err(e) => format!("{{\"error\": \"{}\"}}", e),
867 }
868 }
869 0x0016 => {
870 match decode_tx_total_count(tlv_value) {
871 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
872 Err(e) => format!("{{\"error\": \"{}\"}}", e),
873 }
874 }
875 0x0017 => {
876 match decode_tx_unicast_count(tlv_value) {
877 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
878 Err(e) => format!("{{\"error\": \"{}\"}}", e),
879 }
880 }
881 0x0018 => {
882 match decode_tx_broadcast_count(tlv_value) {
883 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
884 Err(e) => format!("{{\"error\": \"{}\"}}", e),
885 }
886 }
887 0x0019 => {
888 match decode_tx_ack_requested_count(tlv_value) {
889 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
890 Err(e) => format!("{{\"error\": \"{}\"}}", e),
891 }
892 }
893 0x001A => {
894 match decode_tx_acked_count(tlv_value) {
895 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
896 Err(e) => format!("{{\"error\": \"{}\"}}", e),
897 }
898 }
899 0x001B => {
900 match decode_tx_no_ack_requested_count(tlv_value) {
901 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
902 Err(e) => format!("{{\"error\": \"{}\"}}", e),
903 }
904 }
905 0x001C => {
906 match decode_tx_data_count(tlv_value) {
907 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
908 Err(e) => format!("{{\"error\": \"{}\"}}", e),
909 }
910 }
911 0x001D => {
912 match decode_tx_data_poll_count(tlv_value) {
913 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
914 Err(e) => format!("{{\"error\": \"{}\"}}", e),
915 }
916 }
917 0x001E => {
918 match decode_tx_beacon_count(tlv_value) {
919 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
920 Err(e) => format!("{{\"error\": \"{}\"}}", e),
921 }
922 }
923 0x001F => {
924 match decode_tx_beacon_request_count(tlv_value) {
925 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
926 Err(e) => format!("{{\"error\": \"{}\"}}", e),
927 }
928 }
929 0x0020 => {
930 match decode_tx_other_count(tlv_value) {
931 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
932 Err(e) => format!("{{\"error\": \"{}\"}}", e),
933 }
934 }
935 0x0021 => {
936 match decode_tx_retry_count(tlv_value) {
937 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
938 Err(e) => format!("{{\"error\": \"{}\"}}", e),
939 }
940 }
941 0x0022 => {
942 match decode_tx_direct_max_retry_expiry_count(tlv_value) {
943 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
944 Err(e) => format!("{{\"error\": \"{}\"}}", e),
945 }
946 }
947 0x0023 => {
948 match decode_tx_indirect_max_retry_expiry_count(tlv_value) {
949 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
950 Err(e) => format!("{{\"error\": \"{}\"}}", e),
951 }
952 }
953 0x0024 => {
954 match decode_tx_err_cca_count(tlv_value) {
955 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
956 Err(e) => format!("{{\"error\": \"{}\"}}", e),
957 }
958 }
959 0x0025 => {
960 match decode_tx_err_abort_count(tlv_value) {
961 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
962 Err(e) => format!("{{\"error\": \"{}\"}}", e),
963 }
964 }
965 0x0026 => {
966 match decode_tx_err_busy_channel_count(tlv_value) {
967 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
968 Err(e) => format!("{{\"error\": \"{}\"}}", e),
969 }
970 }
971 0x0027 => {
972 match decode_rx_total_count(tlv_value) {
973 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
974 Err(e) => format!("{{\"error\": \"{}\"}}", e),
975 }
976 }
977 0x0028 => {
978 match decode_rx_unicast_count(tlv_value) {
979 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
980 Err(e) => format!("{{\"error\": \"{}\"}}", e),
981 }
982 }
983 0x0029 => {
984 match decode_rx_broadcast_count(tlv_value) {
985 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
986 Err(e) => format!("{{\"error\": \"{}\"}}", e),
987 }
988 }
989 0x002A => {
990 match decode_rx_data_count(tlv_value) {
991 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
992 Err(e) => format!("{{\"error\": \"{}\"}}", e),
993 }
994 }
995 0x002B => {
996 match decode_rx_data_poll_count(tlv_value) {
997 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
998 Err(e) => format!("{{\"error\": \"{}\"}}", e),
999 }
1000 }
1001 0x002C => {
1002 match decode_rx_beacon_count(tlv_value) {
1003 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1004 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1005 }
1006 }
1007 0x002D => {
1008 match decode_rx_beacon_request_count(tlv_value) {
1009 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1010 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1011 }
1012 }
1013 0x002E => {
1014 match decode_rx_other_count(tlv_value) {
1015 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1016 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1017 }
1018 }
1019 0x002F => {
1020 match decode_rx_address_filtered_count(tlv_value) {
1021 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1022 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1023 }
1024 }
1025 0x0030 => {
1026 match decode_rx_dest_addr_filtered_count(tlv_value) {
1027 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1028 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1029 }
1030 }
1031 0x0031 => {
1032 match decode_rx_duplicated_count(tlv_value) {
1033 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1034 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1035 }
1036 }
1037 0x0032 => {
1038 match decode_rx_err_no_frame_count(tlv_value) {
1039 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1040 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1041 }
1042 }
1043 0x0033 => {
1044 match decode_rx_err_unknown_neighbor_count(tlv_value) {
1045 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1046 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1047 }
1048 }
1049 0x0034 => {
1050 match decode_rx_err_invalid_src_addr_count(tlv_value) {
1051 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1052 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1053 }
1054 }
1055 0x0035 => {
1056 match decode_rx_err_sec_count(tlv_value) {
1057 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1058 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1059 }
1060 }
1061 0x0036 => {
1062 match decode_rx_err_fcs_count(tlv_value) {
1063 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1064 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1065 }
1066 }
1067 0x0037 => {
1068 match decode_rx_err_other_count(tlv_value) {
1069 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1070 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1071 }
1072 }
1073 0x0038 => {
1074 match decode_active_timestamp(tlv_value) {
1075 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1076 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1077 }
1078 }
1079 0x0039 => {
1080 match decode_pending_timestamp(tlv_value) {
1081 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1082 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1083 }
1084 }
1085 0x003A => {
1086 match decode_delay(tlv_value) {
1087 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1088 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1089 }
1090 }
1091 0x003B => {
1092 match decode_security_policy(tlv_value) {
1093 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1094 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1095 }
1096 }
1097 0x003C => {
1098 match decode_channel_page0_mask(tlv_value) {
1099 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1100 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1101 }
1102 }
1103 0x003D => {
1104 match decode_operational_dataset_components(tlv_value) {
1105 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1106 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1107 }
1108 }
1109 0x003E => {
1110 match decode_active_network_faults_list(tlv_value) {
1111 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1112 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1113 }
1114 }
1115 0x003F => {
1116 match decode_ext_address(tlv_value) {
1117 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1118 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1119 }
1120 }
1121 0x0040 => {
1122 match decode_rloc16(tlv_value) {
1123 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1124 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1125 }
1126 }
1127 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
1128 }
1129}
1130
1131pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
1136 vec![
1137 (0x0000, "Channel"),
1138 (0x0001, "RoutingRole"),
1139 (0x0002, "NetworkName"),
1140 (0x0003, "PanId"),
1141 (0x0004, "ExtendedPanId"),
1142 (0x0005, "MeshLocalPrefix"),
1143 (0x0006, "OverrunCount"),
1144 (0x0007, "NeighborTable"),
1145 (0x0008, "RouteTable"),
1146 (0x0009, "PartitionId"),
1147 (0x000A, "Weighting"),
1148 (0x000B, "DataVersion"),
1149 (0x000C, "StableDataVersion"),
1150 (0x000D, "LeaderRouterId"),
1151 (0x000E, "DetachedRoleCount"),
1152 (0x000F, "ChildRoleCount"),
1153 (0x0010, "RouterRoleCount"),
1154 (0x0011, "LeaderRoleCount"),
1155 (0x0012, "AttachAttemptCount"),
1156 (0x0013, "PartitionIdChangeCount"),
1157 (0x0014, "BetterPartitionAttachAttemptCount"),
1158 (0x0015, "ParentChangeCount"),
1159 (0x0016, "TxTotalCount"),
1160 (0x0017, "TxUnicastCount"),
1161 (0x0018, "TxBroadcastCount"),
1162 (0x0019, "TxAckRequestedCount"),
1163 (0x001A, "TxAckedCount"),
1164 (0x001B, "TxNoAckRequestedCount"),
1165 (0x001C, "TxDataCount"),
1166 (0x001D, "TxDataPollCount"),
1167 (0x001E, "TxBeaconCount"),
1168 (0x001F, "TxBeaconRequestCount"),
1169 (0x0020, "TxOtherCount"),
1170 (0x0021, "TxRetryCount"),
1171 (0x0022, "TxDirectMaxRetryExpiryCount"),
1172 (0x0023, "TxIndirectMaxRetryExpiryCount"),
1173 (0x0024, "TxErrCcaCount"),
1174 (0x0025, "TxErrAbortCount"),
1175 (0x0026, "TxErrBusyChannelCount"),
1176 (0x0027, "RxTotalCount"),
1177 (0x0028, "RxUnicastCount"),
1178 (0x0029, "RxBroadcastCount"),
1179 (0x002A, "RxDataCount"),
1180 (0x002B, "RxDataPollCount"),
1181 (0x002C, "RxBeaconCount"),
1182 (0x002D, "RxBeaconRequestCount"),
1183 (0x002E, "RxOtherCount"),
1184 (0x002F, "RxAddressFilteredCount"),
1185 (0x0030, "RxDestAddrFilteredCount"),
1186 (0x0031, "RxDuplicatedCount"),
1187 (0x0032, "RxErrNoFrameCount"),
1188 (0x0033, "RxErrUnknownNeighborCount"),
1189 (0x0034, "RxErrInvalidSrcAddrCount"),
1190 (0x0035, "RxErrSecCount"),
1191 (0x0036, "RxErrFcsCount"),
1192 (0x0037, "RxErrOtherCount"),
1193 (0x0038, "ActiveTimestamp"),
1194 (0x0039, "PendingTimestamp"),
1195 (0x003A, "Delay"),
1196 (0x003B, "SecurityPolicy"),
1197 (0x003C, "ChannelPage0Mask"),
1198 (0x003D, "OperationalDatasetComponents"),
1199 (0x003E, "ActiveNetworkFaultsList"),
1200 (0x003F, "ExtAddress"),
1201 (0x0040, "Rloc16"),
1202 ]
1203}
1204