1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, serde::Serialize)]
14pub struct Credential {
15 pub credential_type: Option<u8>,
16 pub credential_index: Option<u16>,
17}
18
19pub fn encode_lock_door(pin_code: Vec<u8>) -> anyhow::Result<Vec<u8>> {
23 let tlv = tlv::TlvItemEnc {
24 tag: 0,
25 value: tlv::TlvItemValueEnc::StructInvisible(vec![
26 (0, tlv::TlvItemValueEnc::OctetString(pin_code)).into(),
27 ]),
28 };
29 Ok(tlv.encode()?)
30}
31
32pub fn encode_unlock_door(pin_code: Vec<u8>) -> anyhow::Result<Vec<u8>> {
34 let tlv = tlv::TlvItemEnc {
35 tag: 0,
36 value: tlv::TlvItemValueEnc::StructInvisible(vec![
37 (0, tlv::TlvItemValueEnc::OctetString(pin_code)).into(),
38 ]),
39 };
40 Ok(tlv.encode()?)
41}
42
43pub fn encode_unlock_with_timeout(timeout: u16, pin_code: Vec<u8>) -> anyhow::Result<Vec<u8>> {
45 let tlv = tlv::TlvItemEnc {
46 tag: 0,
47 value: tlv::TlvItemValueEnc::StructInvisible(vec![
48 (0, tlv::TlvItemValueEnc::UInt16(timeout)).into(),
49 (1, tlv::TlvItemValueEnc::OctetString(pin_code)).into(),
50 ]),
51 };
52 Ok(tlv.encode()?)
53}
54
55pub fn encode_set_pin_code(user_id: u16, user_status: Option<u8>, user_type: Option<u8>, pin: Vec<u8>) -> anyhow::Result<Vec<u8>> {
57 let tlv = tlv::TlvItemEnc {
58 tag: 0,
59 value: tlv::TlvItemValueEnc::StructInvisible(vec![
60 (0, tlv::TlvItemValueEnc::UInt16(user_id)).into(),
61 (1, tlv::TlvItemValueEnc::UInt8(user_status.unwrap_or(0))).into(),
62 (2, tlv::TlvItemValueEnc::UInt8(user_type.unwrap_or(0))).into(),
63 (3, tlv::TlvItemValueEnc::OctetString(pin)).into(),
64 ]),
65 };
66 Ok(tlv.encode()?)
67}
68
69pub fn encode_get_pin_code(user_id: u16) -> anyhow::Result<Vec<u8>> {
71 let tlv = tlv::TlvItemEnc {
72 tag: 0,
73 value: tlv::TlvItemValueEnc::StructInvisible(vec![
74 (0, tlv::TlvItemValueEnc::UInt16(user_id)).into(),
75 ]),
76 };
77 Ok(tlv.encode()?)
78}
79
80pub fn encode_clear_pin_code(pin_slot_index: u16) -> anyhow::Result<Vec<u8>> {
82 let tlv = tlv::TlvItemEnc {
83 tag: 0,
84 value: tlv::TlvItemValueEnc::StructInvisible(vec![
85 (0, tlv::TlvItemValueEnc::UInt16(pin_slot_index)).into(),
86 ]),
87 };
88 Ok(tlv.encode()?)
89}
90
91pub fn encode_set_user_status(user_id: u16, user_status: u8) -> anyhow::Result<Vec<u8>> {
93 let tlv = tlv::TlvItemEnc {
94 tag: 0,
95 value: tlv::TlvItemValueEnc::StructInvisible(vec![
96 (0, tlv::TlvItemValueEnc::UInt16(user_id)).into(),
97 (1, tlv::TlvItemValueEnc::UInt8(user_status)).into(),
98 ]),
99 };
100 Ok(tlv.encode()?)
101}
102
103pub fn encode_get_user_status(user_id: u16) -> anyhow::Result<Vec<u8>> {
105 let tlv = tlv::TlvItemEnc {
106 tag: 0,
107 value: tlv::TlvItemValueEnc::StructInvisible(vec![
108 (0, tlv::TlvItemValueEnc::UInt16(user_id)).into(),
109 ]),
110 };
111 Ok(tlv.encode()?)
112}
113
114pub fn encode_set_week_day_schedule(week_day_index: u8, user_index: u16, days_mask: u8, start_hour: u8, start_minute: u8, end_hour: u8, end_minute: u8) -> anyhow::Result<Vec<u8>> {
116 let tlv = tlv::TlvItemEnc {
117 tag: 0,
118 value: tlv::TlvItemValueEnc::StructInvisible(vec![
119 (0, tlv::TlvItemValueEnc::UInt8(week_day_index)).into(),
120 (1, tlv::TlvItemValueEnc::UInt16(user_index)).into(),
121 (2, tlv::TlvItemValueEnc::UInt8(days_mask)).into(),
122 (3, tlv::TlvItemValueEnc::UInt8(start_hour)).into(),
123 (4, tlv::TlvItemValueEnc::UInt8(start_minute)).into(),
124 (5, tlv::TlvItemValueEnc::UInt8(end_hour)).into(),
125 (6, tlv::TlvItemValueEnc::UInt8(end_minute)).into(),
126 ]),
127 };
128 Ok(tlv.encode()?)
129}
130
131pub fn encode_get_week_day_schedule(week_day_index: u8, user_index: u16) -> anyhow::Result<Vec<u8>> {
133 let tlv = tlv::TlvItemEnc {
134 tag: 0,
135 value: tlv::TlvItemValueEnc::StructInvisible(vec![
136 (0, tlv::TlvItemValueEnc::UInt8(week_day_index)).into(),
137 (1, tlv::TlvItemValueEnc::UInt16(user_index)).into(),
138 ]),
139 };
140 Ok(tlv.encode()?)
141}
142
143pub fn encode_clear_week_day_schedule(week_day_index: u8, user_index: u16) -> anyhow::Result<Vec<u8>> {
145 let tlv = tlv::TlvItemEnc {
146 tag: 0,
147 value: tlv::TlvItemValueEnc::StructInvisible(vec![
148 (0, tlv::TlvItemValueEnc::UInt8(week_day_index)).into(),
149 (1, tlv::TlvItemValueEnc::UInt16(user_index)).into(),
150 ]),
151 };
152 Ok(tlv.encode()?)
153}
154
155pub fn encode_set_year_day_schedule(year_day_index: u8, user_index: u16, local_start_time: u64, local_end_time: u64) -> anyhow::Result<Vec<u8>> {
157 let tlv = tlv::TlvItemEnc {
158 tag: 0,
159 value: tlv::TlvItemValueEnc::StructInvisible(vec![
160 (0, tlv::TlvItemValueEnc::UInt8(year_day_index)).into(),
161 (1, tlv::TlvItemValueEnc::UInt16(user_index)).into(),
162 (2, tlv::TlvItemValueEnc::UInt64(local_start_time)).into(),
163 (3, tlv::TlvItemValueEnc::UInt64(local_end_time)).into(),
164 ]),
165 };
166 Ok(tlv.encode()?)
167}
168
169pub fn encode_get_year_day_schedule(year_day_index: u8, user_index: u16) -> anyhow::Result<Vec<u8>> {
171 let tlv = tlv::TlvItemEnc {
172 tag: 0,
173 value: tlv::TlvItemValueEnc::StructInvisible(vec![
174 (0, tlv::TlvItemValueEnc::UInt8(year_day_index)).into(),
175 (1, tlv::TlvItemValueEnc::UInt16(user_index)).into(),
176 ]),
177 };
178 Ok(tlv.encode()?)
179}
180
181pub fn encode_clear_year_day_schedule(year_day_index: u8, user_index: u16) -> anyhow::Result<Vec<u8>> {
183 let tlv = tlv::TlvItemEnc {
184 tag: 0,
185 value: tlv::TlvItemValueEnc::StructInvisible(vec![
186 (0, tlv::TlvItemValueEnc::UInt8(year_day_index)).into(),
187 (1, tlv::TlvItemValueEnc::UInt16(user_index)).into(),
188 ]),
189 };
190 Ok(tlv.encode()?)
191}
192
193pub fn encode_set_holiday_schedule(holiday_index: u8, local_start_time: u64, local_end_time: u64, operating_mode: u8) -> anyhow::Result<Vec<u8>> {
195 let tlv = tlv::TlvItemEnc {
196 tag: 0,
197 value: tlv::TlvItemValueEnc::StructInvisible(vec![
198 (0, tlv::TlvItemValueEnc::UInt8(holiday_index)).into(),
199 (1, tlv::TlvItemValueEnc::UInt64(local_start_time)).into(),
200 (2, tlv::TlvItemValueEnc::UInt64(local_end_time)).into(),
201 (3, tlv::TlvItemValueEnc::UInt8(operating_mode)).into(),
202 ]),
203 };
204 Ok(tlv.encode()?)
205}
206
207pub fn encode_get_holiday_schedule(holiday_index: u8) -> anyhow::Result<Vec<u8>> {
209 let tlv = tlv::TlvItemEnc {
210 tag: 0,
211 value: tlv::TlvItemValueEnc::StructInvisible(vec![
212 (0, tlv::TlvItemValueEnc::UInt8(holiday_index)).into(),
213 ]),
214 };
215 Ok(tlv.encode()?)
216}
217
218pub fn encode_clear_holiday_schedule(holiday_index: u8) -> anyhow::Result<Vec<u8>> {
220 let tlv = tlv::TlvItemEnc {
221 tag: 0,
222 value: tlv::TlvItemValueEnc::StructInvisible(vec![
223 (0, tlv::TlvItemValueEnc::UInt8(holiday_index)).into(),
224 ]),
225 };
226 Ok(tlv.encode()?)
227}
228
229pub fn encode_set_user_type(user_id: u16, user_type: u8) -> anyhow::Result<Vec<u8>> {
231 let tlv = tlv::TlvItemEnc {
232 tag: 0,
233 value: tlv::TlvItemValueEnc::StructInvisible(vec![
234 (0, tlv::TlvItemValueEnc::UInt16(user_id)).into(),
235 (1, tlv::TlvItemValueEnc::UInt8(user_type)).into(),
236 ]),
237 };
238 Ok(tlv.encode()?)
239}
240
241pub fn encode_get_user_type(user_id: u16) -> anyhow::Result<Vec<u8>> {
243 let tlv = tlv::TlvItemEnc {
244 tag: 0,
245 value: tlv::TlvItemValueEnc::StructInvisible(vec![
246 (0, tlv::TlvItemValueEnc::UInt16(user_id)).into(),
247 ]),
248 };
249 Ok(tlv.encode()?)
250}
251
252pub fn encode_set_rfid_code(user_id: u16, user_status: Option<u8>, user_type: Option<u8>, rfid_code: Vec<u8>) -> anyhow::Result<Vec<u8>> {
254 let tlv = tlv::TlvItemEnc {
255 tag: 0,
256 value: tlv::TlvItemValueEnc::StructInvisible(vec![
257 (0, tlv::TlvItemValueEnc::UInt16(user_id)).into(),
258 (1, tlv::TlvItemValueEnc::UInt8(user_status.unwrap_or(0))).into(),
259 (2, tlv::TlvItemValueEnc::UInt8(user_type.unwrap_or(0))).into(),
260 (3, tlv::TlvItemValueEnc::OctetString(rfid_code)).into(),
261 ]),
262 };
263 Ok(tlv.encode()?)
264}
265
266pub fn encode_get_rfid_code(user_id: u16) -> anyhow::Result<Vec<u8>> {
268 let tlv = tlv::TlvItemEnc {
269 tag: 0,
270 value: tlv::TlvItemValueEnc::StructInvisible(vec![
271 (0, tlv::TlvItemValueEnc::UInt16(user_id)).into(),
272 ]),
273 };
274 Ok(tlv.encode()?)
275}
276
277pub fn encode_clear_rfid_code(rfid_slot_index: u16) -> anyhow::Result<Vec<u8>> {
279 let tlv = tlv::TlvItemEnc {
280 tag: 0,
281 value: tlv::TlvItemValueEnc::StructInvisible(vec![
282 (0, tlv::TlvItemValueEnc::UInt16(rfid_slot_index)).into(),
283 ]),
284 };
285 Ok(tlv.encode()?)
286}
287
288pub fn encode_set_user(operation_type: u8, user_index: u16, user_name: Option<String>, user_unique_id: Option<u32>, user_status: Option<u8>, user_type: Option<u8>, credential_rule: Option<u8>) -> anyhow::Result<Vec<u8>> {
290 let tlv = tlv::TlvItemEnc {
291 tag: 0,
292 value: tlv::TlvItemValueEnc::StructInvisible(vec![
293 (0, tlv::TlvItemValueEnc::UInt8(operation_type)).into(),
294 (1, tlv::TlvItemValueEnc::UInt16(user_index)).into(),
295 (2, tlv::TlvItemValueEnc::String(user_name.unwrap_or("".to_string()))).into(),
296 (3, tlv::TlvItemValueEnc::UInt32(user_unique_id.unwrap_or(0))).into(),
297 (4, tlv::TlvItemValueEnc::UInt8(user_status.unwrap_or(0))).into(),
298 (5, tlv::TlvItemValueEnc::UInt8(user_type.unwrap_or(0))).into(),
299 (6, tlv::TlvItemValueEnc::UInt8(credential_rule.unwrap_or(0))).into(),
300 ]),
301 };
302 Ok(tlv.encode()?)
303}
304
305pub fn encode_get_user(user_index: u16) -> anyhow::Result<Vec<u8>> {
307 let tlv = tlv::TlvItemEnc {
308 tag: 0,
309 value: tlv::TlvItemValueEnc::StructInvisible(vec![
310 (0, tlv::TlvItemValueEnc::UInt16(user_index)).into(),
311 ]),
312 };
313 Ok(tlv.encode()?)
314}
315
316pub fn encode_clear_user(user_index: u16) -> anyhow::Result<Vec<u8>> {
318 let tlv = tlv::TlvItemEnc {
319 tag: 0,
320 value: tlv::TlvItemValueEnc::StructInvisible(vec![
321 (0, tlv::TlvItemValueEnc::UInt16(user_index)).into(),
322 ]),
323 };
324 Ok(tlv.encode()?)
325}
326
327pub fn encode_set_credential(operation_type: u8, credential: u8, credential_data: Vec<u8>, user_index: Option<u16>, user_status: Option<u8>, user_type: Option<u8>) -> anyhow::Result<Vec<u8>> {
329 let tlv = tlv::TlvItemEnc {
330 tag: 0,
331 value: tlv::TlvItemValueEnc::StructInvisible(vec![
332 (0, tlv::TlvItemValueEnc::UInt8(operation_type)).into(),
333 (1, tlv::TlvItemValueEnc::UInt8(credential)).into(),
334 (2, tlv::TlvItemValueEnc::OctetString(credential_data)).into(),
335 (3, tlv::TlvItemValueEnc::UInt16(user_index.unwrap_or(0))).into(),
336 (4, tlv::TlvItemValueEnc::UInt8(user_status.unwrap_or(0))).into(),
337 (5, tlv::TlvItemValueEnc::UInt8(user_type.unwrap_or(0))).into(),
338 ]),
339 };
340 Ok(tlv.encode()?)
341}
342
343pub fn encode_get_credential_status(credential: u8) -> anyhow::Result<Vec<u8>> {
345 let tlv = tlv::TlvItemEnc {
346 tag: 0,
347 value: tlv::TlvItemValueEnc::StructInvisible(vec![
348 (0, tlv::TlvItemValueEnc::UInt8(credential)).into(),
349 ]),
350 };
351 Ok(tlv.encode()?)
352}
353
354pub fn encode_clear_credential(credential: Option<u8>) -> anyhow::Result<Vec<u8>> {
356 let tlv = tlv::TlvItemEnc {
357 tag: 0,
358 value: tlv::TlvItemValueEnc::StructInvisible(vec![
359 (0, tlv::TlvItemValueEnc::UInt8(credential.unwrap_or(0))).into(),
360 ]),
361 };
362 Ok(tlv.encode()?)
363}
364
365pub fn encode_unbolt_door(pin_code: Vec<u8>) -> anyhow::Result<Vec<u8>> {
367 let tlv = tlv::TlvItemEnc {
368 tag: 0,
369 value: tlv::TlvItemValueEnc::StructInvisible(vec![
370 (0, tlv::TlvItemValueEnc::OctetString(pin_code)).into(),
371 ]),
372 };
373 Ok(tlv.encode()?)
374}
375
376pub fn encode_set_aliro_reader_config(signing_key: Vec<u8>, verification_key: Vec<u8>, group_identifier: Vec<u8>, group_resolving_key: Vec<u8>) -> anyhow::Result<Vec<u8>> {
378 let tlv = tlv::TlvItemEnc {
379 tag: 0,
380 value: tlv::TlvItemValueEnc::StructInvisible(vec![
381 (0, tlv::TlvItemValueEnc::OctetString(signing_key)).into(),
382 (1, tlv::TlvItemValueEnc::OctetString(verification_key)).into(),
383 (2, tlv::TlvItemValueEnc::OctetString(group_identifier)).into(),
384 (3, tlv::TlvItemValueEnc::OctetString(group_resolving_key)).into(),
385 ]),
386 };
387 Ok(tlv.encode()?)
388}
389
390pub fn decode_lock_state(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
394 if let tlv::TlvItemValue::Int(v) = inp {
395 Ok(Some(*v as u8))
396 } else {
397 Ok(None)
398 }
399}
400
401pub fn decode_lock_type(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
403 if let tlv::TlvItemValue::Int(v) = inp {
404 Ok(*v as u8)
405 } else {
406 Err(anyhow::anyhow!("Expected Integer"))
407 }
408}
409
410pub fn decode_actuator_enabled(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
412 if let tlv::TlvItemValue::Bool(v) = inp {
413 Ok(*v)
414 } else {
415 Err(anyhow::anyhow!("Expected Bool"))
416 }
417}
418
419pub fn decode_door_state(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
421 if let tlv::TlvItemValue::Int(v) = inp {
422 Ok(Some(*v as u8))
423 } else {
424 Ok(None)
425 }
426}
427
428pub fn decode_door_open_events(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
430 if let tlv::TlvItemValue::Int(v) = inp {
431 Ok(*v as u32)
432 } else {
433 Err(anyhow::anyhow!("Expected Integer"))
434 }
435}
436
437pub fn decode_door_closed_events(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
439 if let tlv::TlvItemValue::Int(v) = inp {
440 Ok(*v as u32)
441 } else {
442 Err(anyhow::anyhow!("Expected Integer"))
443 }
444}
445
446pub fn decode_open_period(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
448 if let tlv::TlvItemValue::Int(v) = inp {
449 Ok(*v as u16)
450 } else {
451 Err(anyhow::anyhow!("Expected Integer"))
452 }
453}
454
455pub fn decode_number_of_total_users_supported(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
457 if let tlv::TlvItemValue::Int(v) = inp {
458 Ok(*v as u16)
459 } else {
460 Err(anyhow::anyhow!("Expected Integer"))
461 }
462}
463
464pub fn decode_number_of_pin_users_supported(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
466 if let tlv::TlvItemValue::Int(v) = inp {
467 Ok(*v as u16)
468 } else {
469 Err(anyhow::anyhow!("Expected Integer"))
470 }
471}
472
473pub fn decode_number_of_rfid_users_supported(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
475 if let tlv::TlvItemValue::Int(v) = inp {
476 Ok(*v as u16)
477 } else {
478 Err(anyhow::anyhow!("Expected Integer"))
479 }
480}
481
482pub fn decode_number_of_week_day_schedules_supported_per_user(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
484 if let tlv::TlvItemValue::Int(v) = inp {
485 Ok(*v as u8)
486 } else {
487 Err(anyhow::anyhow!("Expected Integer"))
488 }
489}
490
491pub fn decode_number_of_year_day_schedules_supported_per_user(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
493 if let tlv::TlvItemValue::Int(v) = inp {
494 Ok(*v as u8)
495 } else {
496 Err(anyhow::anyhow!("Expected Integer"))
497 }
498}
499
500pub fn decode_number_of_holiday_schedules_supported(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
502 if let tlv::TlvItemValue::Int(v) = inp {
503 Ok(*v as u8)
504 } else {
505 Err(anyhow::anyhow!("Expected Integer"))
506 }
507}
508
509pub fn decode_max_pin_code_length(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
511 if let tlv::TlvItemValue::Int(v) = inp {
512 Ok(*v as u8)
513 } else {
514 Err(anyhow::anyhow!("Expected Integer"))
515 }
516}
517
518pub fn decode_min_pin_code_length(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
520 if let tlv::TlvItemValue::Int(v) = inp {
521 Ok(*v as u8)
522 } else {
523 Err(anyhow::anyhow!("Expected Integer"))
524 }
525}
526
527pub fn decode_max_rfid_code_length(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
529 if let tlv::TlvItemValue::Int(v) = inp {
530 Ok(*v as u8)
531 } else {
532 Err(anyhow::anyhow!("Expected Integer"))
533 }
534}
535
536pub fn decode_min_rfid_code_length(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
538 if let tlv::TlvItemValue::Int(v) = inp {
539 Ok(*v as u8)
540 } else {
541 Err(anyhow::anyhow!("Expected Integer"))
542 }
543}
544
545pub fn decode_credential_rules_support(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
547 if let tlv::TlvItemValue::Int(v) = inp {
548 Ok(*v as u8)
549 } else {
550 Err(anyhow::anyhow!("Expected Integer"))
551 }
552}
553
554pub fn decode_number_of_credentials_supported_per_user(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
556 if let tlv::TlvItemValue::Int(v) = inp {
557 Ok(*v as u8)
558 } else {
559 Err(anyhow::anyhow!("Expected Integer"))
560 }
561}
562
563pub fn decode_language(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
565 if let tlv::TlvItemValue::String(v) = inp {
566 Ok(v.clone())
567 } else {
568 Err(anyhow::anyhow!("Expected String"))
569 }
570}
571
572pub fn decode_led_settings(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
574 if let tlv::TlvItemValue::Int(v) = inp {
575 Ok(*v as u8)
576 } else {
577 Err(anyhow::anyhow!("Expected Integer"))
578 }
579}
580
581pub fn decode_auto_relock_time(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
583 if let tlv::TlvItemValue::Int(v) = inp {
584 Ok(*v as u32)
585 } else {
586 Err(anyhow::anyhow!("Expected Integer"))
587 }
588}
589
590pub fn decode_sound_volume(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
592 if let tlv::TlvItemValue::Int(v) = inp {
593 Ok(*v as u8)
594 } else {
595 Err(anyhow::anyhow!("Expected Integer"))
596 }
597}
598
599pub fn decode_operating_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
601 if let tlv::TlvItemValue::Int(v) = inp {
602 Ok(*v as u8)
603 } else {
604 Err(anyhow::anyhow!("Expected Integer"))
605 }
606}
607
608pub fn decode_supported_operating_modes(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
610 if let tlv::TlvItemValue::Int(v) = inp {
611 Ok(*v as u8)
612 } else {
613 Err(anyhow::anyhow!("Expected Integer"))
614 }
615}
616
617pub fn decode_default_configuration_register(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
619 if let tlv::TlvItemValue::Int(v) = inp {
620 Ok(*v as u8)
621 } else {
622 Err(anyhow::anyhow!("Expected Integer"))
623 }
624}
625
626pub fn decode_enable_local_programming(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
628 if let tlv::TlvItemValue::Bool(v) = inp {
629 Ok(*v)
630 } else {
631 Err(anyhow::anyhow!("Expected Bool"))
632 }
633}
634
635pub fn decode_enable_one_touch_locking(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
637 if let tlv::TlvItemValue::Bool(v) = inp {
638 Ok(*v)
639 } else {
640 Err(anyhow::anyhow!("Expected Bool"))
641 }
642}
643
644pub fn decode_enable_inside_status_led(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
646 if let tlv::TlvItemValue::Bool(v) = inp {
647 Ok(*v)
648 } else {
649 Err(anyhow::anyhow!("Expected Bool"))
650 }
651}
652
653pub fn decode_enable_privacy_mode_button(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
655 if let tlv::TlvItemValue::Bool(v) = inp {
656 Ok(*v)
657 } else {
658 Err(anyhow::anyhow!("Expected Bool"))
659 }
660}
661
662pub fn decode_local_programming_features(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
664 if let tlv::TlvItemValue::Int(v) = inp {
665 Ok(*v as u8)
666 } else {
667 Err(anyhow::anyhow!("Expected Integer"))
668 }
669}
670
671pub fn decode_wrong_code_entry_limit(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
673 if let tlv::TlvItemValue::Int(v) = inp {
674 Ok(*v as u8)
675 } else {
676 Err(anyhow::anyhow!("Expected Integer"))
677 }
678}
679
680pub fn decode_user_code_temporary_disable_time(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
682 if let tlv::TlvItemValue::Int(v) = inp {
683 Ok(*v as u8)
684 } else {
685 Err(anyhow::anyhow!("Expected Integer"))
686 }
687}
688
689pub fn decode_send_pin_over_the_air(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
691 if let tlv::TlvItemValue::Bool(v) = inp {
692 Ok(*v)
693 } else {
694 Err(anyhow::anyhow!("Expected Bool"))
695 }
696}
697
698pub fn decode_require_pinfor_remote_operation(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
700 if let tlv::TlvItemValue::Bool(v) = inp {
701 Ok(*v)
702 } else {
703 Err(anyhow::anyhow!("Expected Bool"))
704 }
705}
706
707pub fn decode_security_level(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
709 if let tlv::TlvItemValue::Int(v) = inp {
710 Ok(*v as u8)
711 } else {
712 Err(anyhow::anyhow!("Expected Integer"))
713 }
714}
715
716pub fn decode_expiring_user_timeout(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
718 if let tlv::TlvItemValue::Int(v) = inp {
719 Ok(*v as u16)
720 } else {
721 Err(anyhow::anyhow!("Expected Integer"))
722 }
723}
724
725pub fn decode_aliro_reader_verification_key(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<Vec<u8>>> {
727 if let tlv::TlvItemValue::OctetString(v) = inp {
728 Ok(Some(v.clone()))
729 } else {
730 Ok(None)
731 }
732}
733
734pub fn decode_aliro_reader_group_identifier(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<Vec<u8>>> {
736 if let tlv::TlvItemValue::OctetString(v) = inp {
737 Ok(Some(v.clone()))
738 } else {
739 Ok(None)
740 }
741}
742
743pub fn decode_aliro_reader_group_sub_identifier(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
745 if let tlv::TlvItemValue::OctetString(v) = inp {
746 Ok(v.clone())
747 } else {
748 Err(anyhow::anyhow!("Expected OctetString"))
749 }
750}
751
752pub fn decode_aliro_expedited_transaction_supported_protocol_versions(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<Vec<u8>>> {
754 let mut res = Vec::new();
755 if let tlv::TlvItemValue::List(v) = inp {
756 for item in v {
757 if let tlv::TlvItemValue::OctetString(o) = &item.value {
758 res.push(o.clone());
759 }
760 }
761 }
762 Ok(res)
763}
764
765pub fn decode_aliro_group_resolving_key(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<Vec<u8>>> {
767 if let tlv::TlvItemValue::OctetString(v) = inp {
768 Ok(Some(v.clone()))
769 } else {
770 Ok(None)
771 }
772}
773
774pub fn decode_aliro_supported_bleuwb_protocol_versions(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<Vec<u8>>> {
776 let mut res = Vec::new();
777 if let tlv::TlvItemValue::List(v) = inp {
778 for item in v {
779 if let tlv::TlvItemValue::OctetString(o) = &item.value {
780 res.push(o.clone());
781 }
782 }
783 }
784 Ok(res)
785}
786
787pub fn decode_aliro_ble_advertising_version(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
789 if let tlv::TlvItemValue::Int(v) = inp {
790 Ok(*v as u8)
791 } else {
792 Err(anyhow::anyhow!("Expected Integer"))
793 }
794}
795
796pub fn decode_number_of_aliro_credential_issuer_keys_supported(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
798 if let tlv::TlvItemValue::Int(v) = inp {
799 Ok(*v as u16)
800 } else {
801 Err(anyhow::anyhow!("Expected Integer"))
802 }
803}
804
805pub fn decode_number_of_aliro_endpoint_keys_supported(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
807 if let tlv::TlvItemValue::Int(v) = inp {
808 Ok(*v as u16)
809 } else {
810 Err(anyhow::anyhow!("Expected Integer"))
811 }
812}
813
814
815pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
827 if cluster_id != 0x0101 {
829 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0101, got {}\"}}", cluster_id);
830 }
831
832 match attribute_id {
833 0x0000 => {
834 match decode_lock_state(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 0x0001 => {
840 match decode_lock_type(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 0x0002 => {
846 match decode_actuator_enabled(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 0x0003 => {
852 match decode_door_state(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 0x0004 => {
858 match decode_door_open_events(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 0x0005 => {
864 match decode_door_closed_events(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 0x0006 => {
870 match decode_open_period(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 0x0011 => {
876 match decode_number_of_total_users_supported(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 0x0012 => {
882 match decode_number_of_pin_users_supported(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 0x0013 => {
888 match decode_number_of_rfid_users_supported(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 0x0014 => {
894 match decode_number_of_week_day_schedules_supported_per_user(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 0x0015 => {
900 match decode_number_of_year_day_schedules_supported_per_user(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 0x0016 => {
906 match decode_number_of_holiday_schedules_supported(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 0x0017 => {
912 match decode_max_pin_code_length(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 0x0018 => {
918 match decode_min_pin_code_length(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 0x0019 => {
924 match decode_max_rfid_code_length(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 0x001A => {
930 match decode_min_rfid_code_length(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 0x001B => {
936 match decode_credential_rules_support(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 0x001C => {
942 match decode_number_of_credentials_supported_per_user(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 0x0021 => {
948 match decode_language(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 0x0022 => {
954 match decode_led_settings(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 0x0023 => {
960 match decode_auto_relock_time(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 0x0024 => {
966 match decode_sound_volume(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 0x0025 => {
972 match decode_operating_mode(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 0x0026 => {
978 match decode_supported_operating_modes(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 0x0027 => {
984 match decode_default_configuration_register(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 0x0028 => {
990 match decode_enable_local_programming(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 0x0029 => {
996 match decode_enable_one_touch_locking(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 0x002A => {
1002 match decode_enable_inside_status_led(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 0x002B => {
1008 match decode_enable_privacy_mode_button(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 0x002C => {
1014 match decode_local_programming_features(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 0x0030 => {
1020 match decode_wrong_code_entry_limit(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 0x0031 => {
1026 match decode_user_code_temporary_disable_time(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 0x0032 => {
1032 match decode_send_pin_over_the_air(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 0x0033 => {
1038 match decode_require_pinfor_remote_operation(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 0x0034 => {
1044 match decode_security_level(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 0x0035 => {
1050 match decode_expiring_user_timeout(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 0x0080 => {
1056 match decode_aliro_reader_verification_key(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 0x0081 => {
1062 match decode_aliro_reader_group_identifier(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 0x0082 => {
1068 match decode_aliro_reader_group_sub_identifier(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 0x0083 => {
1074 match decode_aliro_expedited_transaction_supported_protocol_versions(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 0x0084 => {
1080 match decode_aliro_group_resolving_key(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 0x0085 => {
1086 match decode_aliro_supported_bleuwb_protocol_versions(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 0x0086 => {
1092 match decode_aliro_ble_advertising_version(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 0x0087 => {
1098 match decode_number_of_aliro_credential_issuer_keys_supported(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 0x0088 => {
1104 match decode_number_of_aliro_endpoint_keys_supported(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 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
1110 }
1111}
1112
1113pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
1118 vec![
1119 (0x0000, "LockState"),
1120 (0x0001, "LockType"),
1121 (0x0002, "ActuatorEnabled"),
1122 (0x0003, "DoorState"),
1123 (0x0004, "DoorOpenEvents"),
1124 (0x0005, "DoorClosedEvents"),
1125 (0x0006, "OpenPeriod"),
1126 (0x0011, "NumberOfTotalUsersSupported"),
1127 (0x0012, "NumberOfPINUsersSupported"),
1128 (0x0013, "NumberOfRFIDUsersSupported"),
1129 (0x0014, "NumberOfWeekDaySchedulesSupportedPerUser"),
1130 (0x0015, "NumberOfYearDaySchedulesSupportedPerUser"),
1131 (0x0016, "NumberOfHolidaySchedulesSupported"),
1132 (0x0017, "MaxPINCodeLength"),
1133 (0x0018, "MinPINCodeLength"),
1134 (0x0019, "MaxRFIDCodeLength"),
1135 (0x001A, "MinRFIDCodeLength"),
1136 (0x001B, "CredentialRulesSupport"),
1137 (0x001C, "NumberOfCredentialsSupportedPerUser"),
1138 (0x0021, "Language"),
1139 (0x0022, "LEDSettings"),
1140 (0x0023, "AutoRelockTime"),
1141 (0x0024, "SoundVolume"),
1142 (0x0025, "OperatingMode"),
1143 (0x0026, "SupportedOperatingModes"),
1144 (0x0027, "DefaultConfigurationRegister"),
1145 (0x0028, "EnableLocalProgramming"),
1146 (0x0029, "EnableOneTouchLocking"),
1147 (0x002A, "EnableInsideStatusLED"),
1148 (0x002B, "EnablePrivacyModeButton"),
1149 (0x002C, "LocalProgrammingFeatures"),
1150 (0x0030, "WrongCodeEntryLimit"),
1151 (0x0031, "UserCodeTemporaryDisableTime"),
1152 (0x0032, "SendPINOverTheAir"),
1153 (0x0033, "RequirePINforRemoteOperation"),
1154 (0x0034, "SecurityLevel"),
1155 (0x0035, "ExpiringUserTimeout"),
1156 (0x0080, "AliroReaderVerificationKey"),
1157 (0x0081, "AliroReaderGroupIdentifier"),
1158 (0x0082, "AliroReaderGroupSubIdentifier"),
1159 (0x0083, "AliroExpeditedTransactionSupportedProtocolVersions"),
1160 (0x0084, "AliroGroupResolvingKey"),
1161 (0x0085, "AliroSupportedBLEUWBProtocolVersions"),
1162 (0x0086, "AliroBLEAdvertisingVersion"),
1163 (0x0087, "NumberOfAliroCredentialIssuerKeysSupported"),
1164 (0x0088, "NumberOfAliroEndpointKeysSupported"),
1165 ]
1166}
1167