tinkerforge_async/bindings/
nfc_bricklet.rs

1/* ***********************************************************
2 * This file was automatically generated on 2024-02-16.      *
3 *                                                           *
4 * Rust Bindings Version 2.0.20                              *
5 *                                                           *
6 * If you have a bugfix for this file and want to commit it, *
7 * please fix the bug in the generator. You can find a link  *
8 * to the generators git repository on tinkerforge.com       *
9 *************************************************************/
10
11//! NFC tag read/write, NFC P2P and Card Emulation.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/NFC_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, converting_receiver::BrickletRecvTimeoutError, device::*, error::TinkerforgeError,
17    ip_connection::async_io::AsyncIpConnection, low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum NfcBrickletFunction {
24    SetMode,
25    GetMode,
26    ReaderRequestTagId,
27    ReaderGetTagIdLowLevel,
28    ReaderGetState,
29    ReaderWriteNdefLowLevel,
30    ReaderRequestNdef,
31    ReaderReadNdefLowLevel,
32    ReaderAuthenticateMifareClassicPage,
33    ReaderWritePageLowLevel,
34    ReaderRequestPage,
35    ReaderReadPageLowLevel,
36    CardemuGetState,
37    CardemuStartDiscovery,
38    CardemuWriteNdefLowLevel,
39    CardemuStartTransfer,
40    P2pGetState,
41    P2pStartDiscovery,
42    P2pWriteNdefLowLevel,
43    P2pStartTransfer,
44    P2pReadNdefLowLevel,
45    SetDetectionLedConfig,
46    GetDetectionLedConfig,
47    SetMaximumTimeout,
48    GetMaximumTimeout,
49    SimpleGetTagIdLowLevel,
50    GetSpitfpErrorCount,
51    SetBootloaderMode,
52    GetBootloaderMode,
53    SetWriteFirmwarePointer,
54    WriteFirmware,
55    SetStatusLedConfig,
56    GetStatusLedConfig,
57    GetChipTemperature,
58    Reset,
59    WriteUid,
60    ReadUid,
61    GetIdentity,
62    CallbackReaderStateChanged,
63    CallbackCardemuStateChanged,
64    CallbackP2pStateChanged,
65}
66impl From<NfcBrickletFunction> for u8 {
67    fn from(fun: NfcBrickletFunction) -> Self {
68        match fun {
69            NfcBrickletFunction::SetMode => 1,
70            NfcBrickletFunction::GetMode => 2,
71            NfcBrickletFunction::ReaderRequestTagId => 3,
72            NfcBrickletFunction::ReaderGetTagIdLowLevel => 4,
73            NfcBrickletFunction::ReaderGetState => 5,
74            NfcBrickletFunction::ReaderWriteNdefLowLevel => 6,
75            NfcBrickletFunction::ReaderRequestNdef => 7,
76            NfcBrickletFunction::ReaderReadNdefLowLevel => 8,
77            NfcBrickletFunction::ReaderAuthenticateMifareClassicPage => 9,
78            NfcBrickletFunction::ReaderWritePageLowLevel => 10,
79            NfcBrickletFunction::ReaderRequestPage => 11,
80            NfcBrickletFunction::ReaderReadPageLowLevel => 12,
81            NfcBrickletFunction::CardemuGetState => 14,
82            NfcBrickletFunction::CardemuStartDiscovery => 15,
83            NfcBrickletFunction::CardemuWriteNdefLowLevel => 16,
84            NfcBrickletFunction::CardemuStartTransfer => 17,
85            NfcBrickletFunction::P2pGetState => 19,
86            NfcBrickletFunction::P2pStartDiscovery => 20,
87            NfcBrickletFunction::P2pWriteNdefLowLevel => 21,
88            NfcBrickletFunction::P2pStartTransfer => 22,
89            NfcBrickletFunction::P2pReadNdefLowLevel => 23,
90            NfcBrickletFunction::SetDetectionLedConfig => 25,
91            NfcBrickletFunction::GetDetectionLedConfig => 26,
92            NfcBrickletFunction::SetMaximumTimeout => 27,
93            NfcBrickletFunction::GetMaximumTimeout => 28,
94            NfcBrickletFunction::SimpleGetTagIdLowLevel => 29,
95            NfcBrickletFunction::GetSpitfpErrorCount => 234,
96            NfcBrickletFunction::SetBootloaderMode => 235,
97            NfcBrickletFunction::GetBootloaderMode => 236,
98            NfcBrickletFunction::SetWriteFirmwarePointer => 237,
99            NfcBrickletFunction::WriteFirmware => 238,
100            NfcBrickletFunction::SetStatusLedConfig => 239,
101            NfcBrickletFunction::GetStatusLedConfig => 240,
102            NfcBrickletFunction::GetChipTemperature => 242,
103            NfcBrickletFunction::Reset => 243,
104            NfcBrickletFunction::WriteUid => 248,
105            NfcBrickletFunction::ReadUid => 249,
106            NfcBrickletFunction::GetIdentity => 255,
107            NfcBrickletFunction::CallbackReaderStateChanged => 13,
108            NfcBrickletFunction::CallbackCardemuStateChanged => 18,
109            NfcBrickletFunction::CallbackP2pStateChanged => 24,
110        }
111    }
112}
113pub const NFC_BRICKLET_MODE_OFF: u8 = 0;
114pub const NFC_BRICKLET_MODE_CARDEMU: u8 = 1;
115pub const NFC_BRICKLET_MODE_P2P: u8 = 2;
116pub const NFC_BRICKLET_MODE_READER: u8 = 3;
117pub const NFC_BRICKLET_MODE_SIMPLE: u8 = 4;
118pub const NFC_BRICKLET_TAG_TYPE_MIFARE_CLASSIC: u8 = 0;
119pub const NFC_BRICKLET_TAG_TYPE_TYPE1: u8 = 1;
120pub const NFC_BRICKLET_TAG_TYPE_TYPE2: u8 = 2;
121pub const NFC_BRICKLET_TAG_TYPE_TYPE3: u8 = 3;
122pub const NFC_BRICKLET_TAG_TYPE_TYPE4: u8 = 4;
123pub const NFC_BRICKLET_READER_STATE_INITIALIZATION: u8 = 0;
124pub const NFC_BRICKLET_READER_STATE_IDLE: u8 = 128;
125pub const NFC_BRICKLET_READER_STATE_ERROR: u8 = 192;
126pub const NFC_BRICKLET_READER_STATE_REQUEST_TAG_ID: u8 = 2;
127pub const NFC_BRICKLET_READER_STATE_REQUEST_TAG_ID_READY: u8 = 130;
128pub const NFC_BRICKLET_READER_STATE_REQUEST_TAG_ID_ERROR: u8 = 194;
129pub const NFC_BRICKLET_READER_STATE_AUTHENTICATE_MIFARE_CLASSIC_PAGE: u8 = 3;
130pub const NFC_BRICKLET_READER_STATE_AUTHENTICATE_MIFARE_CLASSIC_PAGE_READY: u8 = 131;
131pub const NFC_BRICKLET_READER_STATE_AUTHENTICATE_MIFARE_CLASSIC_PAGE_ERROR: u8 = 195;
132pub const NFC_BRICKLET_READER_STATE_WRITE_PAGE: u8 = 4;
133pub const NFC_BRICKLET_READER_STATE_WRITE_PAGE_READY: u8 = 132;
134pub const NFC_BRICKLET_READER_STATE_WRITE_PAGE_ERROR: u8 = 196;
135pub const NFC_BRICKLET_READER_STATE_REQUEST_PAGE: u8 = 5;
136pub const NFC_BRICKLET_READER_STATE_REQUEST_PAGE_READY: u8 = 133;
137pub const NFC_BRICKLET_READER_STATE_REQUEST_PAGE_ERROR: u8 = 197;
138pub const NFC_BRICKLET_READER_STATE_WRITE_NDEF: u8 = 6;
139pub const NFC_BRICKLET_READER_STATE_WRITE_NDEF_READY: u8 = 134;
140pub const NFC_BRICKLET_READER_STATE_WRITE_NDEF_ERROR: u8 = 198;
141pub const NFC_BRICKLET_READER_STATE_REQUEST_NDEF: u8 = 7;
142pub const NFC_BRICKLET_READER_STATE_REQUEST_NDEF_READY: u8 = 135;
143pub const NFC_BRICKLET_READER_STATE_REQUEST_NDEF_ERROR: u8 = 199;
144pub const NFC_BRICKLET_KEY_A: u8 = 0;
145pub const NFC_BRICKLET_KEY_B: u8 = 1;
146pub const NFC_BRICKLET_READER_WRITE_TYPE4_CAPABILITY_CONTAINER: u16 = 3;
147pub const NFC_BRICKLET_READER_WRITE_TYPE4_NDEF: u16 = 4;
148pub const NFC_BRICKLET_READER_REQUEST_TYPE4_CAPABILITY_CONTAINER: u16 = 3;
149pub const NFC_BRICKLET_READER_REQUEST_TYPE4_NDEF: u16 = 4;
150pub const NFC_BRICKLET_CARDEMU_STATE_INITIALIZATION: u8 = 0;
151pub const NFC_BRICKLET_CARDEMU_STATE_IDLE: u8 = 128;
152pub const NFC_BRICKLET_CARDEMU_STATE_ERROR: u8 = 192;
153pub const NFC_BRICKLET_CARDEMU_STATE_DISCOVER: u8 = 2;
154pub const NFC_BRICKLET_CARDEMU_STATE_DISCOVER_READY: u8 = 130;
155pub const NFC_BRICKLET_CARDEMU_STATE_DISCOVER_ERROR: u8 = 194;
156pub const NFC_BRICKLET_CARDEMU_STATE_TRANSFER_NDEF: u8 = 3;
157pub const NFC_BRICKLET_CARDEMU_STATE_TRANSFER_NDEF_READY: u8 = 131;
158pub const NFC_BRICKLET_CARDEMU_STATE_TRANSFER_NDEF_ERROR: u8 = 195;
159pub const NFC_BRICKLET_CARDEMU_TRANSFER_ABORT: u8 = 0;
160pub const NFC_BRICKLET_CARDEMU_TRANSFER_WRITE: u8 = 1;
161pub const NFC_BRICKLET_P2P_STATE_INITIALIZATION: u8 = 0;
162pub const NFC_BRICKLET_P2P_STATE_IDLE: u8 = 128;
163pub const NFC_BRICKLET_P2P_STATE_ERROR: u8 = 192;
164pub const NFC_BRICKLET_P2P_STATE_DISCOVER: u8 = 2;
165pub const NFC_BRICKLET_P2P_STATE_DISCOVER_READY: u8 = 130;
166pub const NFC_BRICKLET_P2P_STATE_DISCOVER_ERROR: u8 = 194;
167pub const NFC_BRICKLET_P2P_STATE_TRANSFER_NDEF: u8 = 3;
168pub const NFC_BRICKLET_P2P_STATE_TRANSFER_NDEF_READY: u8 = 131;
169pub const NFC_BRICKLET_P2P_STATE_TRANSFER_NDEF_ERROR: u8 = 195;
170pub const NFC_BRICKLET_P2P_TRANSFER_ABORT: u8 = 0;
171pub const NFC_BRICKLET_P2P_TRANSFER_WRITE: u8 = 1;
172pub const NFC_BRICKLET_P2P_TRANSFER_READ: u8 = 2;
173pub const NFC_BRICKLET_DETECTION_LED_CONFIG_OFF: u8 = 0;
174pub const NFC_BRICKLET_DETECTION_LED_CONFIG_ON: u8 = 1;
175pub const NFC_BRICKLET_DETECTION_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
176pub const NFC_BRICKLET_DETECTION_LED_CONFIG_SHOW_DETECTION: u8 = 3;
177pub const NFC_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
178pub const NFC_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
179pub const NFC_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
180pub const NFC_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
181pub const NFC_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
182pub const NFC_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
183pub const NFC_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
184pub const NFC_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
185pub const NFC_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
186pub const NFC_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
187pub const NFC_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
188pub const NFC_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
189pub const NFC_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
190pub const NFC_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
191pub const NFC_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
192
193#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
194pub struct ReaderGetTagIdLowLevel {
195    pub tag_type: u8,
196    pub tag_id_length: u8,
197    pub tag_id_data: [u8; 32],
198}
199impl FromByteSlice for ReaderGetTagIdLowLevel {
200    fn bytes_expected() -> usize {
201        34
202    }
203    fn from_le_byte_slice(bytes: &[u8]) -> ReaderGetTagIdLowLevel {
204        ReaderGetTagIdLowLevel {
205            tag_type: <u8>::from_le_byte_slice(&bytes[0..1]),
206            tag_id_length: <u8>::from_le_byte_slice(&bytes[1..2]),
207            tag_id_data: <[u8; 32]>::from_le_byte_slice(&bytes[2..34]),
208        }
209    }
210}
211impl LowLevelRead<u8, ReaderGetTagIdResult> for ReaderGetTagIdLowLevel {
212    fn ll_message_length(&self) -> usize {
213        self.tag_id_length as usize
214    }
215
216    fn ll_message_chunk_offset(&self) -> usize {
217        0
218    }
219
220    fn ll_message_chunk_data(&self) -> &[u8] {
221        &self.tag_id_data
222    }
223
224    fn get_result(&self) -> ReaderGetTagIdResult {
225        ReaderGetTagIdResult { tag_type: self.tag_type }
226    }
227}
228
229#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
230pub struct ReaderGetState {
231    pub state: u8,
232    pub idle: bool,
233}
234impl FromByteSlice for ReaderGetState {
235    fn bytes_expected() -> usize {
236        2
237    }
238    fn from_le_byte_slice(bytes: &[u8]) -> ReaderGetState {
239        ReaderGetState { state: <u8>::from_le_byte_slice(&bytes[0..1]), idle: <bool>::from_le_byte_slice(&bytes[1..2]) }
240    }
241}
242
243#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
244pub struct ReaderWriteNdefLowLevel {}
245impl FromByteSlice for ReaderWriteNdefLowLevel {
246    fn bytes_expected() -> usize {
247        0
248    }
249    fn from_le_byte_slice(_bytes: &[u8]) -> ReaderWriteNdefLowLevel {
250        ReaderWriteNdefLowLevel {}
251    }
252}
253
254#[derive(Clone, Copy)]
255pub struct ReaderReadNdefLowLevel {
256    pub ndef_length: u16,
257    pub ndef_chunk_offset: u16,
258    pub ndef_chunk_data: [u8; 60],
259}
260impl FromByteSlice for ReaderReadNdefLowLevel {
261    fn bytes_expected() -> usize {
262        64
263    }
264    fn from_le_byte_slice(bytes: &[u8]) -> ReaderReadNdefLowLevel {
265        ReaderReadNdefLowLevel {
266            ndef_length: <u16>::from_le_byte_slice(&bytes[0..2]),
267            ndef_chunk_offset: <u16>::from_le_byte_slice(&bytes[2..4]),
268            ndef_chunk_data: <[u8; 60]>::from_le_byte_slice(&bytes[4..64]),
269        }
270    }
271}
272impl LowLevelRead<u8, ReaderReadNdefResult> for ReaderReadNdefLowLevel {
273    fn ll_message_length(&self) -> usize {
274        self.ndef_length as usize
275    }
276
277    fn ll_message_chunk_offset(&self) -> usize {
278        self.ndef_chunk_offset as usize
279    }
280
281    fn ll_message_chunk_data(&self) -> &[u8] {
282        &self.ndef_chunk_data
283    }
284
285    fn get_result(&self) -> ReaderReadNdefResult {
286        ReaderReadNdefResult {}
287    }
288}
289
290#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
291pub struct ReaderWritePageLowLevel {}
292impl FromByteSlice for ReaderWritePageLowLevel {
293    fn bytes_expected() -> usize {
294        0
295    }
296    fn from_le_byte_slice(_bytes: &[u8]) -> ReaderWritePageLowLevel {
297        ReaderWritePageLowLevel {}
298    }
299}
300
301#[derive(Clone, Copy)]
302pub struct ReaderReadPageLowLevel {
303    pub data_length: u16,
304    pub data_chunk_offset: u16,
305    pub data_chunk_data: [u8; 60],
306}
307impl FromByteSlice for ReaderReadPageLowLevel {
308    fn bytes_expected() -> usize {
309        64
310    }
311    fn from_le_byte_slice(bytes: &[u8]) -> ReaderReadPageLowLevel {
312        ReaderReadPageLowLevel {
313            data_length: <u16>::from_le_byte_slice(&bytes[0..2]),
314            data_chunk_offset: <u16>::from_le_byte_slice(&bytes[2..4]),
315            data_chunk_data: <[u8; 60]>::from_le_byte_slice(&bytes[4..64]),
316        }
317    }
318}
319impl LowLevelRead<u8, ReaderReadPageResult> for ReaderReadPageLowLevel {
320    fn ll_message_length(&self) -> usize {
321        self.data_length as usize
322    }
323
324    fn ll_message_chunk_offset(&self) -> usize {
325        self.data_chunk_offset as usize
326    }
327
328    fn ll_message_chunk_data(&self) -> &[u8] {
329        &self.data_chunk_data
330    }
331
332    fn get_result(&self) -> ReaderReadPageResult {
333        ReaderReadPageResult {}
334    }
335}
336
337#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
338pub struct ReaderStateChangedEvent {
339    pub state: u8,
340    pub idle: bool,
341}
342impl FromByteSlice for ReaderStateChangedEvent {
343    fn bytes_expected() -> usize {
344        2
345    }
346    fn from_le_byte_slice(bytes: &[u8]) -> ReaderStateChangedEvent {
347        ReaderStateChangedEvent { state: <u8>::from_le_byte_slice(&bytes[0..1]), idle: <bool>::from_le_byte_slice(&bytes[1..2]) }
348    }
349}
350
351#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
352pub struct CardemuGetState {
353    pub state: u8,
354    pub idle: bool,
355}
356impl FromByteSlice for CardemuGetState {
357    fn bytes_expected() -> usize {
358        2
359    }
360    fn from_le_byte_slice(bytes: &[u8]) -> CardemuGetState {
361        CardemuGetState { state: <u8>::from_le_byte_slice(&bytes[0..1]), idle: <bool>::from_le_byte_slice(&bytes[1..2]) }
362    }
363}
364
365#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
366pub struct CardemuWriteNdefLowLevel {}
367impl FromByteSlice for CardemuWriteNdefLowLevel {
368    fn bytes_expected() -> usize {
369        0
370    }
371    fn from_le_byte_slice(_bytes: &[u8]) -> CardemuWriteNdefLowLevel {
372        CardemuWriteNdefLowLevel {}
373    }
374}
375
376#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
377pub struct CardemuStateChangedEvent {
378    pub state: u8,
379    pub idle: bool,
380}
381impl FromByteSlice for CardemuStateChangedEvent {
382    fn bytes_expected() -> usize {
383        2
384    }
385    fn from_le_byte_slice(bytes: &[u8]) -> CardemuStateChangedEvent {
386        CardemuStateChangedEvent { state: <u8>::from_le_byte_slice(&bytes[0..1]), idle: <bool>::from_le_byte_slice(&bytes[1..2]) }
387    }
388}
389
390#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
391pub struct P2pGetState {
392    pub state: u8,
393    pub idle: bool,
394}
395impl FromByteSlice for P2pGetState {
396    fn bytes_expected() -> usize {
397        2
398    }
399    fn from_le_byte_slice(bytes: &[u8]) -> P2pGetState {
400        P2pGetState { state: <u8>::from_le_byte_slice(&bytes[0..1]), idle: <bool>::from_le_byte_slice(&bytes[1..2]) }
401    }
402}
403
404#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
405pub struct P2pWriteNdefLowLevel {}
406impl FromByteSlice for P2pWriteNdefLowLevel {
407    fn bytes_expected() -> usize {
408        0
409    }
410    fn from_le_byte_slice(_bytes: &[u8]) -> P2pWriteNdefLowLevel {
411        P2pWriteNdefLowLevel {}
412    }
413}
414
415#[derive(Clone, Copy)]
416pub struct P2pReadNdefLowLevel {
417    pub ndef_length: u16,
418    pub ndef_chunk_offset: u16,
419    pub ndef_chunk_data: [u8; 60],
420}
421impl FromByteSlice for P2pReadNdefLowLevel {
422    fn bytes_expected() -> usize {
423        64
424    }
425    fn from_le_byte_slice(bytes: &[u8]) -> P2pReadNdefLowLevel {
426        P2pReadNdefLowLevel {
427            ndef_length: <u16>::from_le_byte_slice(&bytes[0..2]),
428            ndef_chunk_offset: <u16>::from_le_byte_slice(&bytes[2..4]),
429            ndef_chunk_data: <[u8; 60]>::from_le_byte_slice(&bytes[4..64]),
430        }
431    }
432}
433impl LowLevelRead<u8, P2pReadNdefResult> for P2pReadNdefLowLevel {
434    fn ll_message_length(&self) -> usize {
435        self.ndef_length as usize
436    }
437
438    fn ll_message_chunk_offset(&self) -> usize {
439        self.ndef_chunk_offset as usize
440    }
441
442    fn ll_message_chunk_data(&self) -> &[u8] {
443        &self.ndef_chunk_data
444    }
445
446    fn get_result(&self) -> P2pReadNdefResult {
447        P2pReadNdefResult {}
448    }
449}
450
451#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
452pub struct P2pStateChangedEvent {
453    pub state: u8,
454    pub idle: bool,
455}
456impl FromByteSlice for P2pStateChangedEvent {
457    fn bytes_expected() -> usize {
458        2
459    }
460    fn from_le_byte_slice(bytes: &[u8]) -> P2pStateChangedEvent {
461        P2pStateChangedEvent { state: <u8>::from_le_byte_slice(&bytes[0..1]), idle: <bool>::from_le_byte_slice(&bytes[1..2]) }
462    }
463}
464
465#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
466pub struct SimpleGetTagIdLowLevel {
467    pub tag_type: u8,
468    pub tag_id_length: u8,
469    pub tag_id_data: [u8; 10],
470    pub last_seen: u32,
471}
472impl FromByteSlice for SimpleGetTagIdLowLevel {
473    fn bytes_expected() -> usize {
474        16
475    }
476    fn from_le_byte_slice(bytes: &[u8]) -> SimpleGetTagIdLowLevel {
477        SimpleGetTagIdLowLevel {
478            tag_type: <u8>::from_le_byte_slice(&bytes[0..1]),
479            tag_id_length: <u8>::from_le_byte_slice(&bytes[1..2]),
480            tag_id_data: <[u8; 10]>::from_le_byte_slice(&bytes[2..12]),
481            last_seen: <u32>::from_le_byte_slice(&bytes[12..16]),
482        }
483    }
484}
485impl LowLevelRead<u8, SimpleGetTagIdResult> for SimpleGetTagIdLowLevel {
486    fn ll_message_length(&self) -> usize {
487        self.tag_id_length as usize
488    }
489
490    fn ll_message_chunk_offset(&self) -> usize {
491        0
492    }
493
494    fn ll_message_chunk_data(&self) -> &[u8] {
495        &self.tag_id_data
496    }
497
498    fn get_result(&self) -> SimpleGetTagIdResult {
499        SimpleGetTagIdResult { tag_type: self.tag_type, last_seen: self.last_seen }
500    }
501}
502
503#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
504pub struct SpitfpErrorCount {
505    pub error_count_ack_checksum: u32,
506    pub error_count_message_checksum: u32,
507    pub error_count_frame: u32,
508    pub error_count_overflow: u32,
509}
510impl FromByteSlice for SpitfpErrorCount {
511    fn bytes_expected() -> usize {
512        16
513    }
514    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
515        SpitfpErrorCount {
516            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
517            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
518            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
519            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
520        }
521    }
522}
523
524#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
525pub struct Identity {
526    pub uid: String,
527    pub connected_uid: String,
528    pub position: char,
529    pub hardware_version: [u8; 3],
530    pub firmware_version: [u8; 3],
531    pub device_identifier: u16,
532}
533impl FromByteSlice for Identity {
534    fn bytes_expected() -> usize {
535        25
536    }
537    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
538        Identity {
539            uid: <String>::from_le_byte_slice(&bytes[0..8]),
540            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
541            position: <char>::from_le_byte_slice(&bytes[16..17]),
542            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
543            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
544            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
545        }
546    }
547}
548
549#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
550pub struct ReaderGetTagIdResult {
551    pub tag_type: u8,
552}
553
554#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
555pub struct ReaderWriteNdefResult {}
556
557#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
558pub struct ReaderReadNdefResult {}
559
560#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
561pub struct ReaderWritePageResult {}
562
563#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
564pub struct ReaderReadPageResult {}
565
566#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
567pub struct CardemuWriteNdefResult {}
568
569#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
570pub struct P2pWriteNdefResult {}
571
572#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
573pub struct P2pReadNdefResult {}
574
575#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
576pub struct SimpleGetTagIdResult {
577    pub tag_type: u8,
578    pub last_seen: u32,
579}
580
581/// NFC tag read/write, NFC P2P and Card Emulation
582#[derive(Clone)]
583pub struct NfcBricklet {
584    device: Device,
585}
586impl NfcBricklet {
587    pub const DEVICE_IDENTIFIER: u16 = 286;
588    pub const DEVICE_DISPLAY_NAME: &'static str = "NFC Bricklet";
589    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
590    pub fn new(uid: Uid, connection: AsyncIpConnection) -> NfcBricklet {
591        let mut result = NfcBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
592        result.device.response_expected[u8::from(NfcBrickletFunction::SetMode) as usize] = ResponseExpectedFlag::False;
593        result.device.response_expected[u8::from(NfcBrickletFunction::GetMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
594        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderRequestTagId) as usize] = ResponseExpectedFlag::False;
595        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderGetTagIdLowLevel) as usize] = ResponseExpectedFlag::AlwaysTrue;
596        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderGetState) as usize] = ResponseExpectedFlag::AlwaysTrue;
597        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderWriteNdefLowLevel) as usize] = ResponseExpectedFlag::True;
598        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderRequestNdef) as usize] = ResponseExpectedFlag::False;
599        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderReadNdefLowLevel) as usize] = ResponseExpectedFlag::AlwaysTrue;
600        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderAuthenticateMifareClassicPage) as usize] =
601            ResponseExpectedFlag::False;
602        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderWritePageLowLevel) as usize] = ResponseExpectedFlag::True;
603        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderRequestPage) as usize] = ResponseExpectedFlag::False;
604        result.device.response_expected[u8::from(NfcBrickletFunction::ReaderReadPageLowLevel) as usize] = ResponseExpectedFlag::AlwaysTrue;
605        result.device.response_expected[u8::from(NfcBrickletFunction::CardemuGetState) as usize] = ResponseExpectedFlag::AlwaysTrue;
606        result.device.response_expected[u8::from(NfcBrickletFunction::CardemuStartDiscovery) as usize] = ResponseExpectedFlag::False;
607        result.device.response_expected[u8::from(NfcBrickletFunction::CardemuWriteNdefLowLevel) as usize] = ResponseExpectedFlag::True;
608        result.device.response_expected[u8::from(NfcBrickletFunction::CardemuStartTransfer) as usize] = ResponseExpectedFlag::False;
609        result.device.response_expected[u8::from(NfcBrickletFunction::P2pGetState) as usize] = ResponseExpectedFlag::AlwaysTrue;
610        result.device.response_expected[u8::from(NfcBrickletFunction::P2pStartDiscovery) as usize] = ResponseExpectedFlag::False;
611        result.device.response_expected[u8::from(NfcBrickletFunction::P2pWriteNdefLowLevel) as usize] = ResponseExpectedFlag::True;
612        result.device.response_expected[u8::from(NfcBrickletFunction::P2pStartTransfer) as usize] = ResponseExpectedFlag::False;
613        result.device.response_expected[u8::from(NfcBrickletFunction::P2pReadNdefLowLevel) as usize] = ResponseExpectedFlag::AlwaysTrue;
614        result.device.response_expected[u8::from(NfcBrickletFunction::SetDetectionLedConfig) as usize] = ResponseExpectedFlag::False;
615        result.device.response_expected[u8::from(NfcBrickletFunction::GetDetectionLedConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
616        result.device.response_expected[u8::from(NfcBrickletFunction::SetMaximumTimeout) as usize] = ResponseExpectedFlag::False;
617        result.device.response_expected[u8::from(NfcBrickletFunction::GetMaximumTimeout) as usize] = ResponseExpectedFlag::AlwaysTrue;
618        result.device.response_expected[u8::from(NfcBrickletFunction::SimpleGetTagIdLowLevel) as usize] = ResponseExpectedFlag::AlwaysTrue;
619        result.device.response_expected[u8::from(NfcBrickletFunction::GetSpitfpErrorCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
620        result.device.response_expected[u8::from(NfcBrickletFunction::SetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
621        result.device.response_expected[u8::from(NfcBrickletFunction::GetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
622        result.device.response_expected[u8::from(NfcBrickletFunction::SetWriteFirmwarePointer) as usize] = ResponseExpectedFlag::False;
623        result.device.response_expected[u8::from(NfcBrickletFunction::WriteFirmware) as usize] = ResponseExpectedFlag::AlwaysTrue;
624        result.device.response_expected[u8::from(NfcBrickletFunction::SetStatusLedConfig) as usize] = ResponseExpectedFlag::False;
625        result.device.response_expected[u8::from(NfcBrickletFunction::GetStatusLedConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
626        result.device.response_expected[u8::from(NfcBrickletFunction::GetChipTemperature) as usize] = ResponseExpectedFlag::AlwaysTrue;
627        result.device.response_expected[u8::from(NfcBrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
628        result.device.response_expected[u8::from(NfcBrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
629        result.device.response_expected[u8::from(NfcBrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
630        result.device.response_expected[u8::from(NfcBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
631        result
632    }
633
634    /// Returns the response expected flag for the function specified by the function ID parameter.
635    /// It is true if the function is expected to send a response, false otherwise.
636    ///
637    /// For getter functions this is enabled by default and cannot be disabled, because those
638    /// functions will always send a response. For callback configuration functions it is enabled
639    /// by default too, but can be disabled by [`set_response_expected`](crate::nfc_bricklet::NfcBricklet::set_response_expected).
640    /// For setter functions it is disabled by default and can be enabled.
641    ///
642    /// Enabling the response expected flag for a setter function allows to detect timeouts
643    /// and other error conditions calls of this setter as well. The device will then send a response
644    /// for this purpose. If this flag is disabled for a setter function then no response is sent
645    /// and errors are silently ignored, because they cannot be detected.
646    ///
647    /// See [`set_response_expected`](crate::nfc_bricklet::NfcBricklet::set_response_expected) for the list of function ID constants available for this function.
648    pub fn get_response_expected(&mut self, fun: NfcBrickletFunction) -> Result<bool, GetResponseExpectedError> {
649        self.device.get_response_expected(u8::from(fun))
650    }
651
652    /// Changes the response expected flag of the function specified by the function ID parameter.
653    /// This flag can only be changed for setter (default value: false) and callback configuration
654    /// functions (default value: true). For getter functions it is always enabled.
655    ///
656    /// Enabling the response expected flag for a setter function allows to detect timeouts and
657    /// other error conditions calls of this setter as well. The device will then send a response
658    /// for this purpose. If this flag is disabled for a setter function then no response is sent
659    /// and errors are silently ignored, because they cannot be detected.
660    pub fn set_response_expected(&mut self, fun: NfcBrickletFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
661        self.device.set_response_expected(u8::from(fun), response_expected)
662    }
663
664    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
665    pub fn set_response_expected_all(&mut self, response_expected: bool) {
666        self.device.set_response_expected_all(response_expected)
667    }
668
669    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
670    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
671    pub fn get_api_version(&self) -> [u8; 3] {
672        self.device.api_version
673    }
674
675    /// This receiver is called if the reader state of the NFC Bricklet changes.
676    /// See [`reader_get_state`] for more information about the possible states.
677    ///
678    /// [`reader_get_state`]: #method.reader_get_state
679    pub async fn get_reader_state_changed_callback_receiver(&mut self) -> impl Stream<Item = ReaderStateChangedEvent> {
680        self.device
681            .get_callback_receiver(u8::from(NfcBrickletFunction::CallbackReaderStateChanged))
682            .await
683            .map(|p| ReaderStateChangedEvent::from_le_byte_slice(p.body()))
684    }
685
686    /// This receiver is called if the cardemu state of the NFC Bricklet changes.
687    /// See [`cardemu_get_state`] for more information about the possible states.
688    pub async fn get_cardemu_state_changed_callback_receiver(&mut self) -> impl Stream<Item = CardemuStateChangedEvent> {
689        self.device
690            .get_callback_receiver(u8::from(NfcBrickletFunction::CallbackCardemuStateChanged))
691            .await
692            .map(|p| CardemuStateChangedEvent::from_le_byte_slice(p.body()))
693    }
694
695    /// This receiver is called if the P2P state of the NFC Bricklet changes.
696    /// See [`p2p_get_state`] for more information about the possible states.
697    pub async fn get_p2p_state_changed_callback_receiver(&mut self) -> impl Stream<Item = P2pStateChangedEvent> {
698        self.device
699            .get_callback_receiver(u8::from(NfcBrickletFunction::CallbackP2pStateChanged))
700            .await
701            .map(|p| P2pStateChangedEvent::from_le_byte_slice(p.body()))
702    }
703
704    /// Sets the mode. The NFC Bricklet supports four modes:
705    ///
706    /// * Off
707    /// * Card Emulation (Cardemu): Emulates a tag for other readers
708    /// * Peer to Peer (P2P): Exchange data with other readers
709    /// * Reader: Reads and writes tags
710    /// * Simple: Automatically reads tag IDs
711    ///
712    /// If you change a mode, the Bricklet will reconfigure the hardware for this mode.
713    /// Therefore, you can only use functions corresponding to the current mode. For
714    /// example, in Reader mode you can only use Reader functions.
715    ///
716    /// Associated constants:
717    /// * NFC_BRICKLET_MODE_OFF
718    ///	* NFC_BRICKLET_MODE_CARDEMU
719    ///	* NFC_BRICKLET_MODE_P2P
720    ///	* NFC_BRICKLET_MODE_READER
721    ///	* NFC_BRICKLET_MODE_SIMPLE
722    pub async fn set_mode(&mut self, mode: u8) -> Result<(), TinkerforgeError> {
723        let mut payload = [0; 1];
724        mode.write_to_slice(&mut payload[0..1]);
725
726        #[allow(unused_variables)]
727        let result = self.device.set(u8::from(NfcBrickletFunction::SetMode), &payload).await?;
728        Ok(())
729    }
730
731    /// Returns the mode as set by [`set_mode`].
732    ///
733    /// Associated constants:
734    /// * NFC_BRICKLET_MODE_OFF
735    ///	* NFC_BRICKLET_MODE_CARDEMU
736    ///	* NFC_BRICKLET_MODE_P2P
737    ///	* NFC_BRICKLET_MODE_READER
738    ///	* NFC_BRICKLET_MODE_SIMPLE
739    pub async fn get_mode(&mut self) -> Result<u8, TinkerforgeError> {
740        let payload = [0; 0];
741
742        #[allow(unused_variables)]
743        let result = self.device.get(u8::from(NfcBrickletFunction::GetMode), &payload).await?;
744        Ok(u8::from_le_byte_slice(result.body()))
745    }
746
747    /// After you call [`reader_request_tag_id`] the NFC Bricklet will try to read
748    /// the tag ID from the tag. After this process is done the state will change.
749    /// You can either register the [`get_reader_state_changed_callback_receiver`] receiver or you can poll
750    /// [`reader_get_state`] to find out about the state change.
751    ///
752    /// If the state changes to *ReaderRequestTagIDError* it means that either there was
753    /// no tag present or that the tag has an incompatible type. If the state
754    /// changes to *ReaderRequestTagIDReady* it means that a compatible tag was found
755    /// and that the tag ID has been saved. You can now read out the tag ID by
756    /// calling [`reader_get_tag_id`].
757    ///
758    /// If two tags are in the proximity of the NFC Bricklet, this
759    /// function will cycle through the tags. To select a specific tag you have
760    /// to call [`reader_request_tag_id`] until the correct tag ID is found.
761    ///
762    /// In case of any *ReaderError* state the selection is lost and you have to
763    /// start again by calling [`reader_request_tag_id`].
764    pub async fn reader_request_tag_id(&mut self) -> Result<(), TinkerforgeError> {
765        let payload = [0; 0];
766
767        #[allow(unused_variables)]
768        let result = self.device.set(u8::from(NfcBrickletFunction::ReaderRequestTagId), &payload).await?;
769        Ok(())
770    }
771
772    /// Returns the tag type and the tag ID. This function can only be called if the
773    /// NFC Bricklet is currently in one of the *ReaderReady* states. The returned tag ID
774    /// is the tag ID that was saved through the last call of [`reader_request_tag_id`].
775    ///
776    /// To get the tag ID of a tag the approach is as follows:
777    ///
778    /// 1. Call [`reader_request_tag_id`]
779    /// 2. Wait for state to change to *ReaderRequestTagIDReady* (see [`reader_get_state`] or
780    ///    [`get_reader_state_changed_callback_receiver`] receiver)
781    /// 3. Call [`reader_get_tag_id`]
782    ///
783    /// Associated constants:
784    /// * NFC_BRICKLET_TAG_TYPE_MIFARE_CLASSIC
785    ///	* NFC_BRICKLET_TAG_TYPE_TYPE1
786    ///	* NFC_BRICKLET_TAG_TYPE_TYPE2
787    ///	* NFC_BRICKLET_TAG_TYPE_TYPE3
788    ///	* NFC_BRICKLET_TAG_TYPE_TYPE4
789    pub async fn reader_get_tag_id_low_level(&mut self) -> Result<ReaderGetTagIdLowLevel, TinkerforgeError> {
790        let payload = [0; 0];
791
792        #[allow(unused_variables)]
793        let result = self.device.get(u8::from(NfcBrickletFunction::ReaderGetTagIdLowLevel), &payload).await?;
794        Ok(ReaderGetTagIdLowLevel::from_le_byte_slice(result.body()))
795    }
796
797    /// Returns the current reader state of the NFC Bricklet.
798    ///
799    /// On startup the Bricklet will be in the *ReaderInitialization* state. The
800    /// initialization will only take about 20ms. After that it changes to *ReaderIdle*.
801    ///
802    /// The Bricklet is also reinitialized if the mode is changed, see [`set_mode`].
803    ///
804    /// The functions of this Bricklet can be called in the *ReaderIdle* state and all of
805    /// the *ReaderReady* and *ReaderError* states.
806    ///
807    /// Example: If you call [`reader_request_page`], the state will change to
808    /// *ReaderRequestPage* until the reading of the page is finished. Then it will change
809    /// to either *ReaderRequestPageReady* if it worked or to *ReaderRequestPageError* if it
810    /// didn't. If the request worked you can get the page by calling [`reader_read_page`].
811    ///
812    /// The same approach is used analogously for the other API functions.
813    ///
814    /// Associated constants:
815    /// * NFC_BRICKLET_READER_STATE_INITIALIZATION
816    ///	* NFC_BRICKLET_READER_STATE_IDLE
817    ///	* NFC_BRICKLET_READER_STATE_ERROR
818    ///	* NFC_BRICKLET_READER_STATE_REQUEST_TAG_ID
819    ///	* NFC_BRICKLET_READER_STATE_REQUEST_TAG_ID_READY
820    ///	* NFC_BRICKLET_READER_STATE_REQUEST_TAG_ID_ERROR
821    ///	* NFC_BRICKLET_READER_STATE_AUTHENTICATE_MIFARE_CLASSIC_PAGE
822    ///	* NFC_BRICKLET_READER_STATE_AUTHENTICATE_MIFARE_CLASSIC_PAGE_READY
823    ///	* NFC_BRICKLET_READER_STATE_AUTHENTICATE_MIFARE_CLASSIC_PAGE_ERROR
824    ///	* NFC_BRICKLET_READER_STATE_WRITE_PAGE
825    ///	* NFC_BRICKLET_READER_STATE_WRITE_PAGE_READY
826    ///	* NFC_BRICKLET_READER_STATE_WRITE_PAGE_ERROR
827    ///	* NFC_BRICKLET_READER_STATE_REQUEST_PAGE
828    ///	* NFC_BRICKLET_READER_STATE_REQUEST_PAGE_READY
829    ///	* NFC_BRICKLET_READER_STATE_REQUEST_PAGE_ERROR
830    ///	* NFC_BRICKLET_READER_STATE_WRITE_NDEF
831    ///	* NFC_BRICKLET_READER_STATE_WRITE_NDEF_READY
832    ///	* NFC_BRICKLET_READER_STATE_WRITE_NDEF_ERROR
833    ///	* NFC_BRICKLET_READER_STATE_REQUEST_NDEF
834    ///	* NFC_BRICKLET_READER_STATE_REQUEST_NDEF_READY
835    ///	* NFC_BRICKLET_READER_STATE_REQUEST_NDEF_ERROR
836    pub async fn reader_get_state(&mut self) -> Result<ReaderGetState, TinkerforgeError> {
837        let payload = [0; 0];
838
839        #[allow(unused_variables)]
840        let result = self.device.get(u8::from(NfcBrickletFunction::ReaderGetState), &payload).await?;
841        Ok(ReaderGetState::from_le_byte_slice(result.body()))
842    }
843
844    /// Writes NDEF formated data.
845    ///
846    /// This function currently supports NFC Forum Type 2 and 4.
847    ///
848    /// The general approach for writing a NDEF message is as follows:
849    ///
850    /// 1. Call [`reader_request_tag_id`]
851    /// 2. Wait for state to change to *ReaderRequestTagIDReady* (see
852    ///    [`reader_get_state`] or [`get_reader_state_changed_callback_receiver`] receiver)
853    /// 3. If looking for a specific tag then call [`reader_get_tag_id`] and check
854    ///    if the expected tag was found, if it was not found got back to step 1
855    /// 4. Call [`reader_write_ndef`] with the NDEF message that you want to write
856    /// 5. Wait for state to change to *ReaderWriteNDEFReady* (see [`reader_get_state`]
857    ///    or [`get_reader_state_changed_callback_receiver`] receiver)
858    pub async fn reader_write_ndef_low_level(
859        &mut self,
860        ndef_length: u16,
861        ndef_chunk_offset: u16,
862        ndef_chunk_data: &[u8; 60],
863    ) -> Result<ReaderWriteNdefLowLevel, TinkerforgeError> {
864        let mut payload = [0; 64];
865        ndef_length.write_to_slice(&mut payload[0..2]);
866        ndef_chunk_offset.write_to_slice(&mut payload[2..4]);
867        ndef_chunk_data.write_to_slice(&mut payload[4..64]);
868
869        #[allow(unused_variables)]
870        let result = self.device.set(u8::from(NfcBrickletFunction::ReaderWriteNdefLowLevel), &payload).await?.unwrap();
871        Ok(ReaderWriteNdefLowLevel::from_le_byte_slice(result.body()))
872    }
873
874    /// Reads NDEF formated data from a tag.
875    ///
876    /// This function currently supports NFC Forum Type 1, 2, 3 and 4.
877    ///
878    /// The general approach for reading a NDEF message is as follows:
879    ///
880    /// 1. Call [`reader_request_tag_id`]
881    /// 2. Wait for state to change to *RequestTagIDReady* (see [`reader_get_state`]
882    ///    or [`get_reader_state_changed_callback_receiver`] receiver)
883    /// 3. If looking for a specific tag then call [`reader_get_tag_id`] and check if the
884    ///    expected tag was found, if it was not found got back to step 1
885    /// 4. Call [`reader_request_ndef`]
886    /// 5. Wait for state to change to *ReaderRequestNDEFReady* (see [`reader_get_state`]
887    ///    or [`get_reader_state_changed_callback_receiver`] receiver)
888    /// 6. Call [`reader_read_ndef`] to retrieve the NDEF message from the buffer
889    pub async fn reader_request_ndef(&mut self) -> Result<(), TinkerforgeError> {
890        let payload = [0; 0];
891
892        #[allow(unused_variables)]
893        let result = self.device.set(u8::from(NfcBrickletFunction::ReaderRequestNdef), &payload).await?;
894        Ok(())
895    }
896
897    /// Returns the NDEF data from an internal buffer. To fill the buffer
898    /// with a NDEF message you have to call [`reader_request_ndef`] beforehand.
899    pub async fn reader_read_ndef_low_level(&mut self) -> Result<ReaderReadNdefLowLevel, TinkerforgeError> {
900        let payload = [0; 0];
901
902        #[allow(unused_variables)]
903        let result = self.device.get(u8::from(NfcBrickletFunction::ReaderReadNdefLowLevel), &payload).await?;
904        Ok(ReaderReadNdefLowLevel::from_le_byte_slice(result.body()))
905    }
906
907    /// Mifare Classic tags use authentication. If you want to read from or write to
908    /// a Mifare Classic page you have to authenticate it beforehand.
909    /// Each page can be authenticated with two keys: A (``key_number`` = 0) and B
910    /// (``key_number`` = 1). A new Mifare Classic
911    /// tag that has not yet been written to can be accessed with key A
912    /// and the default key ``[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]``.
913    ///
914    /// The approach to read or write a Mifare Classic page is as follows:
915    ///
916    /// 1. Call [`reader_request_tag_id`]
917    /// 2. Wait for state to change to *ReaderRequestTagIDReady* (see [`reader_get_state`]
918    ///    or [`get_reader_state_changed_callback_receiver`] receiver)
919    /// 3. If looking for a specific tag then call [`reader_get_tag_id`] and check if the
920    ///    expected tag was found, if it was not found got back to step 1
921    /// 4. Call [`reader_authenticate_mifare_classic_page`] with page and key for the page
922    /// 5. Wait for state to change to *ReaderAuthenticatingMifareClassicPageReady* (see
923    ///    [`reader_get_state`] or [`get_reader_state_changed_callback_receiver`] receiver)
924    /// 6. Call [`reader_request_page`] or [`reader_write_page`] to read/write page
925    ///
926    /// The authentication will always work for one whole sector (4 pages).
927    ///
928    /// Associated constants:
929    /// * NFC_BRICKLET_KEY_A
930    ///	* NFC_BRICKLET_KEY_B
931    pub async fn reader_authenticate_mifare_classic_page(
932        &mut self,
933        page: u16,
934        key_number: u8,
935        key: &[u8; 6],
936    ) -> Result<(), TinkerforgeError> {
937        let mut payload = [0; 9];
938        page.write_to_slice(&mut payload[0..2]);
939        key_number.write_to_slice(&mut payload[2..3]);
940        key.write_to_slice(&mut payload[3..9]);
941
942        #[allow(unused_variables)]
943        let result = self.device.set(u8::from(NfcBrickletFunction::ReaderAuthenticateMifareClassicPage), &payload).await?;
944        Ok(())
945    }
946
947    /// Writes a maximum of 8192 bytes starting from the given page. How many pages are written
948    /// depends on the tag type. The page sizes are as follows:
949    ///
950    /// * Mifare Classic page size: 16 byte
951    /// * NFC Forum Type 1 page size: 8 byte
952    /// * NFC Forum Type 2 page size: 4 byte
953    /// * NFC Forum Type 3 page size: 16 byte
954    /// * NFC Forum Type 4: No pages, page = file selection (CC or NDEF, see below)
955    ///
956    /// The general approach for writing to a tag is as follows:
957    ///
958    /// 1. Call [`reader_request_tag_id`]
959    /// 2. Wait for state to change to *ReaderRequestTagIDReady* (see [`reader_get_state`] or
960    ///    [`get_reader_state_changed_callback_receiver`] receiver)
961    /// 3. If looking for a specific tag then call [`reader_get_tag_id`] and check if the
962    ///    expected tag was found, if it was not found got back to step 1
963    /// 4. Call [`reader_write_page`] with page number and data
964    /// 5. Wait for state to change to *ReaderWritePageReady* (see [`reader_get_state`] or
965    ///    [`get_reader_state_changed_callback_receiver`] receiver)
966    ///
967    /// If you use a Mifare Classic tag you have to authenticate a page before you
968    /// can write to it. See [`reader_authenticate_mifare_classic_page`].
969    ///
970    /// NFC Forum Type 4 tags are not organized into pages but different files. We currently
971    /// support two files: Capability Container file (CC) and NDEF file.
972    ///
973    /// Choose CC by setting page to 3 or NDEF by setting page to 4.
974    ///
975    /// Associated constants:
976    /// * NFC_BRICKLET_READER_WRITE_TYPE4_CAPABILITY_CONTAINER
977    ///	* NFC_BRICKLET_READER_WRITE_TYPE4_NDEF
978    pub async fn reader_write_page_low_level(
979        &mut self,
980        page: u16,
981        data_length: u16,
982        data_chunk_offset: u16,
983        data_chunk_data: &[u8; 58],
984    ) -> Result<ReaderWritePageLowLevel, TinkerforgeError> {
985        let mut payload = [0; 64];
986        page.write_to_slice(&mut payload[0..2]);
987        data_length.write_to_slice(&mut payload[2..4]);
988        data_chunk_offset.write_to_slice(&mut payload[4..6]);
989        data_chunk_data.write_to_slice(&mut payload[6..64]);
990
991        #[allow(unused_variables)]
992        let result = self.device.set(u8::from(NfcBrickletFunction::ReaderWritePageLowLevel), &payload).await?.unwrap();
993        Ok(ReaderWritePageLowLevel::from_le_byte_slice(result.body()))
994    }
995
996    /// Reads a maximum of 8192 bytes starting from the given page and stores them into a buffer.
997    /// The buffer can then be read out with [`reader_read_page`].
998    /// How many pages are read depends on the tag type. The page sizes are
999    /// as follows:
1000    ///
1001    /// * Mifare Classic page size: 16 byte
1002    /// * NFC Forum Type 1 page size: 8 byte
1003    /// * NFC Forum Type 2 page size: 4 byte
1004    /// * NFC Forum Type 3 page size: 16 byte
1005    /// * NFC Forum Type 4: No pages, page = file selection (CC or NDEF, see below)
1006    ///
1007    /// The general approach for reading a tag is as follows:
1008    ///
1009    /// 1. Call [`reader_request_tag_id`]
1010    /// 2. Wait for state to change to *RequestTagIDReady* (see [`reader_get_state`]
1011    ///    or [`get_reader_state_changed_callback_receiver`] receiver)
1012    /// 3. If looking for a specific tag then call [`reader_get_tag_id`] and check if the
1013    ///    expected tag was found, if it was not found got back to step 1
1014    /// 4. Call [`reader_request_page`] with page number
1015    /// 5. Wait for state to change to *ReaderRequestPageReady* (see [`reader_get_state`]
1016    ///    or [`get_reader_state_changed_callback_receiver`] receiver)
1017    /// 6. Call [`reader_read_page`] to retrieve the page from the buffer
1018    ///
1019    /// If you use a Mifare Classic tag you have to authenticate a page before you
1020    /// can read it. See [`reader_authenticate_mifare_classic_page`].
1021    ///
1022    /// NFC Forum Type 4 tags are not organized into pages but different files. We currently
1023    /// support two files: Capability Container file (CC) and NDEF file.
1024    ///
1025    /// Choose CC by setting page to 3 or NDEF by setting page to 4.
1026    ///
1027    /// Associated constants:
1028    /// * NFC_BRICKLET_READER_REQUEST_TYPE4_CAPABILITY_CONTAINER
1029    ///	* NFC_BRICKLET_READER_REQUEST_TYPE4_NDEF
1030    pub async fn reader_request_page(&mut self, page: u16, length: u16) -> Result<(), TinkerforgeError> {
1031        let mut payload = [0; 4];
1032        page.write_to_slice(&mut payload[0..2]);
1033        length.write_to_slice(&mut payload[2..4]);
1034
1035        #[allow(unused_variables)]
1036        let result = self.device.set(u8::from(NfcBrickletFunction::ReaderRequestPage), &payload).await?;
1037        Ok(())
1038    }
1039
1040    /// Returns the page data from an internal buffer. To fill the buffer
1041    /// with specific pages you have to call [`reader_request_page`] beforehand.
1042    pub async fn reader_read_page_low_level(&mut self) -> Result<ReaderReadPageLowLevel, TinkerforgeError> {
1043        let payload = [0; 0];
1044
1045        #[allow(unused_variables)]
1046        let result = self.device.get(u8::from(NfcBrickletFunction::ReaderReadPageLowLevel), &payload).await?;
1047        Ok(ReaderReadPageLowLevel::from_le_byte_slice(result.body()))
1048    }
1049
1050    /// Returns the current cardemu state of the NFC Bricklet.
1051    ///
1052    /// On startup the Bricklet will be in the *CardemuInitialization* state. The
1053    /// initialization will only take about 20ms. After that it changes to *CardemuIdle*.
1054    ///
1055    /// The Bricklet is also reinitialized if the mode is changed, see [`set_mode`].
1056    ///
1057    /// The functions of this Bricklet can be called in the *CardemuIdle* state and all of
1058    /// the *CardemuReady* and *CardemuError* states.
1059    ///
1060    /// Example: If you call [`cardemu_start_discovery`], the state will change to
1061    /// *CardemuDiscover* until the discovery is finished. Then it will change
1062    /// to either *CardemuDiscoverReady* if it worked or to *CardemuDiscoverError* if it
1063    /// didn't.
1064    ///
1065    /// The same approach is used analogously for the other API functions.
1066    ///
1067    /// Associated constants:
1068    /// * NFC_BRICKLET_CARDEMU_STATE_INITIALIZATION
1069    ///	* NFC_BRICKLET_CARDEMU_STATE_IDLE
1070    ///	* NFC_BRICKLET_CARDEMU_STATE_ERROR
1071    ///	* NFC_BRICKLET_CARDEMU_STATE_DISCOVER
1072    ///	* NFC_BRICKLET_CARDEMU_STATE_DISCOVER_READY
1073    ///	* NFC_BRICKLET_CARDEMU_STATE_DISCOVER_ERROR
1074    ///	* NFC_BRICKLET_CARDEMU_STATE_TRANSFER_NDEF
1075    ///	* NFC_BRICKLET_CARDEMU_STATE_TRANSFER_NDEF_READY
1076    ///	* NFC_BRICKLET_CARDEMU_STATE_TRANSFER_NDEF_ERROR
1077    pub async fn cardemu_get_state(&mut self) -> Result<CardemuGetState, TinkerforgeError> {
1078        let payload = [0; 0];
1079
1080        #[allow(unused_variables)]
1081        let result = self.device.get(u8::from(NfcBrickletFunction::CardemuGetState), &payload).await?;
1082        Ok(CardemuGetState::from_le_byte_slice(result.body()))
1083    }
1084
1085    /// Starts the discovery process. If you call this function while a NFC
1086    /// reader device is near to the NFC Bricklet the state will change from
1087    /// *CardemuDiscovery* to *CardemuDiscoveryReady*.
1088    ///
1089    /// If no NFC reader device can be found or if there is an error during
1090    /// discovery the cardemu state will change to *CardemuDiscoveryError*. In this case you
1091    /// have to restart the discovery process.
1092    ///
1093    /// If the cardemu state changes to *CardemuDiscoveryReady* you can start the NDEF message
1094    /// transfer with [`cardemu_write_ndef`] and [`cardemu_start_transfer`].
1095    pub async fn cardemu_start_discovery(&mut self) -> Result<(), TinkerforgeError> {
1096        let payload = [0; 0];
1097
1098        #[allow(unused_variables)]
1099        let result = self.device.set(u8::from(NfcBrickletFunction::CardemuStartDiscovery), &payload).await?;
1100        Ok(())
1101    }
1102
1103    /// Writes the NDEF message that is to be transferred to the NFC peer.
1104    ///
1105    /// The maximum supported NDEF message size in Cardemu mode is 255 byte.
1106    ///
1107    /// You can call this function at any time in Cardemu mode. The internal buffer
1108    /// will not be overwritten until you call this function again or change the
1109    /// mode.
1110    pub async fn cardemu_write_ndef_low_level(
1111        &mut self,
1112        ndef_length: u16,
1113        ndef_chunk_offset: u16,
1114        ndef_chunk_data: &[u8; 60],
1115    ) -> Result<CardemuWriteNdefLowLevel, TinkerforgeError> {
1116        let mut payload = [0; 64];
1117        ndef_length.write_to_slice(&mut payload[0..2]);
1118        ndef_chunk_offset.write_to_slice(&mut payload[2..4]);
1119        ndef_chunk_data.write_to_slice(&mut payload[4..64]);
1120
1121        #[allow(unused_variables)]
1122        let result = self.device.set(u8::from(NfcBrickletFunction::CardemuWriteNdefLowLevel), &payload).await?.unwrap();
1123        Ok(CardemuWriteNdefLowLevel::from_le_byte_slice(result.body()))
1124    }
1125
1126    /// You can start the transfer of a NDEF message if the cardemu state is *CardemuDiscoveryReady*.
1127    ///
1128    /// Before you call this function to start a write transfer, the NDEF message that
1129    /// is to be transferred has to be written via [`cardemu_write_ndef`] first.
1130    ///
1131    /// After you call this function the state will change to *CardemuTransferNDEF*. It will
1132    /// change to *CardemuTransferNDEFReady* if the transfer was successful or
1133    /// *CardemuTransferNDEFError* if it wasn't.
1134    ///
1135    /// Associated constants:
1136    /// * NFC_BRICKLET_CARDEMU_TRANSFER_ABORT
1137    ///	* NFC_BRICKLET_CARDEMU_TRANSFER_WRITE
1138    pub async fn cardemu_start_transfer(&mut self, transfer: u8) -> Result<(), TinkerforgeError> {
1139        let mut payload = [0; 1];
1140        transfer.write_to_slice(&mut payload[0..1]);
1141
1142        #[allow(unused_variables)]
1143        let result = self.device.set(u8::from(NfcBrickletFunction::CardemuStartTransfer), &payload).await?;
1144        Ok(())
1145    }
1146
1147    /// Returns the current P2P state of the NFC Bricklet.
1148    ///
1149    /// On startup the Bricklet will be in the *P2PInitialization* state. The
1150    /// initialization will only take about 20ms. After that it changes to *P2PIdle*.
1151    ///
1152    /// The Bricklet is also reinitialized if the mode is changed, see [`set_mode`].
1153    ///
1154    /// The functions of this Bricklet can be called in the *P2PIdle* state and all of
1155    /// the *P2PReady* and *P2PError* states.
1156    ///
1157    /// Example: If you call [`p2p_start_discovery`], the state will change to
1158    /// *P2PDiscover* until the discovery is finished. Then it will change
1159    /// to either P2PDiscoverReady* if it worked or to *P2PDiscoverError* if it
1160    /// didn't.
1161    ///
1162    /// The same approach is used analogously for the other API functions.
1163    ///
1164    /// Associated constants:
1165    /// * NFC_BRICKLET_P2P_STATE_INITIALIZATION
1166    ///	* NFC_BRICKLET_P2P_STATE_IDLE
1167    ///	* NFC_BRICKLET_P2P_STATE_ERROR
1168    ///	* NFC_BRICKLET_P2P_STATE_DISCOVER
1169    ///	* NFC_BRICKLET_P2P_STATE_DISCOVER_READY
1170    ///	* NFC_BRICKLET_P2P_STATE_DISCOVER_ERROR
1171    ///	* NFC_BRICKLET_P2P_STATE_TRANSFER_NDEF
1172    ///	* NFC_BRICKLET_P2P_STATE_TRANSFER_NDEF_READY
1173    ///	* NFC_BRICKLET_P2P_STATE_TRANSFER_NDEF_ERROR
1174    pub async fn p2p_get_state(&mut self) -> Result<P2pGetState, TinkerforgeError> {
1175        let payload = [0; 0];
1176
1177        #[allow(unused_variables)]
1178        let result = self.device.get(u8::from(NfcBrickletFunction::P2pGetState), &payload).await?;
1179        Ok(P2pGetState::from_le_byte_slice(result.body()))
1180    }
1181
1182    /// Starts the discovery process. If you call this function while another NFC
1183    /// P2P enabled device is near to the NFC Bricklet the state will change from
1184    /// *P2PDiscovery* to *P2PDiscoveryReady*.
1185    ///
1186    /// If no NFC P2P enabled device can be found or if there is an error during
1187    /// discovery the P2P state will change to *P2PDiscoveryError*. In this case you
1188    /// have to restart the discovery process.
1189    ///
1190    /// If the P2P state changes to *P2PDiscoveryReady* you can start the NDEF message
1191    /// transfer with [`p2p_start_transfer`].
1192    pub async fn p2p_start_discovery(&mut self) -> Result<(), TinkerforgeError> {
1193        let payload = [0; 0];
1194
1195        #[allow(unused_variables)]
1196        let result = self.device.set(u8::from(NfcBrickletFunction::P2pStartDiscovery), &payload).await?;
1197        Ok(())
1198    }
1199
1200    /// Writes the NDEF message that is to be transferred to the NFC peer.
1201    ///
1202    /// The maximum supported NDEF message size for P2P transfer is 255 byte.
1203    ///
1204    /// You can call this function at any time in P2P mode. The internal buffer
1205    /// will not be overwritten until you call this function again, change the
1206    /// mode or use P2P to read an NDEF messages.
1207    pub async fn p2p_write_ndef_low_level(
1208        &mut self,
1209        ndef_length: u16,
1210        ndef_chunk_offset: u16,
1211        ndef_chunk_data: &[u8; 60],
1212    ) -> Result<P2pWriteNdefLowLevel, TinkerforgeError> {
1213        let mut payload = [0; 64];
1214        ndef_length.write_to_slice(&mut payload[0..2]);
1215        ndef_chunk_offset.write_to_slice(&mut payload[2..4]);
1216        ndef_chunk_data.write_to_slice(&mut payload[4..64]);
1217
1218        #[allow(unused_variables)]
1219        let result = self.device.set(u8::from(NfcBrickletFunction::P2pWriteNdefLowLevel), &payload).await?.unwrap();
1220        Ok(P2pWriteNdefLowLevel::from_le_byte_slice(result.body()))
1221    }
1222
1223    /// You can start the transfer of a NDEF message if the P2P state is *P2PDiscoveryReady*.
1224    ///
1225    /// Before you call this function to start a write transfer, the NDEF message that
1226    /// is to be transferred has to be written via [`p2p_write_ndef`] first.
1227    ///
1228    /// After you call this function the P2P state will change to *P2PTransferNDEF*. It will
1229    /// change to *P2PTransferNDEFReady* if the transfer was successfull or
1230    /// *P2PTransferNDEFError* if it wasn't.
1231    ///
1232    /// If you started a write transfer you are now done. If you started a read transfer
1233    /// you can now use [`p2p_read_ndef`] to read the NDEF message that was written
1234    /// by the NFC peer.
1235    ///
1236    /// Associated constants:
1237    /// * NFC_BRICKLET_P2P_TRANSFER_ABORT
1238    ///	* NFC_BRICKLET_P2P_TRANSFER_WRITE
1239    ///	* NFC_BRICKLET_P2P_TRANSFER_READ
1240    pub async fn p2p_start_transfer(&mut self, transfer: u8) -> Result<(), TinkerforgeError> {
1241        let mut payload = [0; 1];
1242        transfer.write_to_slice(&mut payload[0..1]);
1243
1244        #[allow(unused_variables)]
1245        let result = self.device.set(u8::from(NfcBrickletFunction::P2pStartTransfer), &payload).await?;
1246        Ok(())
1247    }
1248
1249    /// Returns the NDEF message that was written by a NFC peer in NFC P2P mode.
1250    ///
1251    /// The NDEF message is ready if you called [`p2p_start_transfer`] with a
1252    /// read transfer and the P2P state changed to *P2PTransferNDEFReady*.
1253    pub async fn p2p_read_ndef_low_level(&mut self) -> Result<P2pReadNdefLowLevel, TinkerforgeError> {
1254        let payload = [0; 0];
1255
1256        #[allow(unused_variables)]
1257        let result = self.device.get(u8::from(NfcBrickletFunction::P2pReadNdefLowLevel), &payload).await?;
1258        Ok(P2pReadNdefLowLevel::from_le_byte_slice(result.body()))
1259    }
1260
1261    /// Sets the detection LED configuration. By default the LED shows
1262    /// if a card/reader is detected.
1263    ///
1264    /// You can also turn the LED permanently on/off or show a heartbeat.
1265    ///
1266    /// If the Bricklet is in bootloader mode, the LED is off.
1267    ///
1268    /// Associated constants:
1269    /// * NFC_BRICKLET_DETECTION_LED_CONFIG_OFF
1270    ///	* NFC_BRICKLET_DETECTION_LED_CONFIG_ON
1271    ///	* NFC_BRICKLET_DETECTION_LED_CONFIG_SHOW_HEARTBEAT
1272    ///	* NFC_BRICKLET_DETECTION_LED_CONFIG_SHOW_DETECTION
1273    pub async fn set_detection_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
1274        let mut payload = [0; 1];
1275        config.write_to_slice(&mut payload[0..1]);
1276
1277        #[allow(unused_variables)]
1278        let result = self.device.set(u8::from(NfcBrickletFunction::SetDetectionLedConfig), &payload).await?;
1279        Ok(())
1280    }
1281
1282    /// Returns the configuration as set by [`set_detection_led_config`]
1283    ///
1284    /// Associated constants:
1285    /// * NFC_BRICKLET_DETECTION_LED_CONFIG_OFF
1286    ///	* NFC_BRICKLET_DETECTION_LED_CONFIG_ON
1287    ///	* NFC_BRICKLET_DETECTION_LED_CONFIG_SHOW_HEARTBEAT
1288    ///	* NFC_BRICKLET_DETECTION_LED_CONFIG_SHOW_DETECTION
1289    pub async fn get_detection_led_config(&mut self) -> Result<u8, TinkerforgeError> {
1290        let payload = [0; 0];
1291
1292        #[allow(unused_variables)]
1293        let result = self.device.get(u8::from(NfcBrickletFunction::GetDetectionLedConfig), &payload).await?;
1294        Ok(u8::from_le_byte_slice(result.body()))
1295    }
1296
1297    /// Sets the maximum timeout.
1298    ///
1299    /// This is a global maximum used for all internal state timeouts. The timeouts depend heavily
1300    /// on the used tags etc. For example: If you use a Type 2 tag and you want to detect if
1301    /// it is present, you have to use [`reader_request_tag_id`] and wait for the state
1302    /// to change to either the error state or the ready state.
1303    ///
1304    /// With the default configuration this takes 2-3 seconds. By setting the maximum timeout to
1305    /// 100ms you can reduce this time to ~150-200ms. For Type 2 this would also still work
1306    /// with a 20ms timeout (a Type 2 tag answers usually within 10ms). A type 4 tag can take
1307    /// up to 500ms in our tests.
1308    ///
1309    /// If you need a fast response time to discover if a tag is present or not you can find
1310    /// a good timeout value by trial and error for your specific tag.
1311    ///
1312    /// By default we use a very conservative timeout, to be sure that any tag can always
1313    /// answer in time.
1314    ///
1315    ///
1316    /// .. versionadded:: 2.0.1$nbsp;(Plugin)
1317    pub async fn set_maximum_timeout(&mut self, timeout: u16) -> Result<(), TinkerforgeError> {
1318        let mut payload = [0; 2];
1319        timeout.write_to_slice(&mut payload[0..2]);
1320
1321        #[allow(unused_variables)]
1322        let result = self.device.set(u8::from(NfcBrickletFunction::SetMaximumTimeout), &payload).await?;
1323        Ok(())
1324    }
1325
1326    /// Returns the timeout as set by [`set_maximum_timeout`]
1327    ///
1328    ///
1329    /// .. versionadded:: 2.0.1$nbsp;(Plugin)
1330    pub async fn get_maximum_timeout(&mut self) -> Result<u16, TinkerforgeError> {
1331        let payload = [0; 0];
1332
1333        #[allow(unused_variables)]
1334        let result = self.device.get(u8::from(NfcBrickletFunction::GetMaximumTimeout), &payload).await?;
1335        Ok(u16::from_le_byte_slice(result.body()))
1336    }
1337
1338    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
1339    ///
1340    /// Associated constants:
1341    /// * NFC_BRICKLET_TAG_TYPE_MIFARE_CLASSIC
1342    ///	* NFC_BRICKLET_TAG_TYPE_TYPE1
1343    ///	* NFC_BRICKLET_TAG_TYPE_TYPE2
1344    ///	* NFC_BRICKLET_TAG_TYPE_TYPE3
1345    ///	* NFC_BRICKLET_TAG_TYPE_TYPE4
1346    pub async fn simple_get_tag_id_low_level(&mut self, index: u8) -> Result<SimpleGetTagIdLowLevel, TinkerforgeError> {
1347        let mut payload = [0; 1];
1348        index.write_to_slice(&mut payload[0..1]);
1349
1350        #[allow(unused_variables)]
1351        let result = self.device.get(u8::from(NfcBrickletFunction::SimpleGetTagIdLowLevel), &payload).await?;
1352        Ok(SimpleGetTagIdLowLevel::from_le_byte_slice(result.body()))
1353    }
1354
1355    /// Returns the error count for the communication between Brick and Bricklet.
1356    ///
1357    /// The errors are divided into
1358    ///
1359    /// * ACK checksum errors,
1360    /// * message checksum errors,
1361    /// * framing errors and
1362    /// * overflow errors.
1363    ///
1364    /// The errors counts are for errors that occur on the Bricklet side. All
1365    /// Bricks have a similar function that returns the errors on the Brick side.
1366    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
1367        let payload = [0; 0];
1368
1369        #[allow(unused_variables)]
1370        let result = self.device.get(u8::from(NfcBrickletFunction::GetSpitfpErrorCount), &payload).await?;
1371        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
1372    }
1373
1374    /// Sets the bootloader mode and returns the status after the requested
1375    /// mode change was instigated.
1376    ///
1377    /// You can change from bootloader mode to firmware mode and vice versa. A change
1378    /// from bootloader mode to firmware mode will only take place if the entry function,
1379    /// device identifier and CRC are present and correct.
1380    ///
1381    /// This function is used by Brick Viewer during flashing. It should not be
1382    /// necessary to call it in a normal user program.
1383    ///
1384    /// Associated constants:
1385    /// * NFC_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
1386    ///	* NFC_BRICKLET_BOOTLOADER_MODE_FIRMWARE
1387    ///	* NFC_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
1388    ///	* NFC_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
1389    ///	* NFC_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
1390    ///	* NFC_BRICKLET_BOOTLOADER_STATUS_OK
1391    ///	* NFC_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
1392    ///	* NFC_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
1393    ///	* NFC_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
1394    ///	* NFC_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
1395    ///	* NFC_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
1396    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
1397        let mut payload = [0; 1];
1398        mode.write_to_slice(&mut payload[0..1]);
1399
1400        #[allow(unused_variables)]
1401        let result = self.device.get(u8::from(NfcBrickletFunction::SetBootloaderMode), &payload).await?;
1402        Ok(u8::from_le_byte_slice(result.body()))
1403    }
1404
1405    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
1406    ///
1407    /// Associated constants:
1408    /// * NFC_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
1409    ///	* NFC_BRICKLET_BOOTLOADER_MODE_FIRMWARE
1410    ///	* NFC_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
1411    ///	* NFC_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
1412    ///	* NFC_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
1413    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
1414        let payload = [0; 0];
1415
1416        #[allow(unused_variables)]
1417        let result = self.device.get(u8::from(NfcBrickletFunction::GetBootloaderMode), &payload).await?;
1418        Ok(u8::from_le_byte_slice(result.body()))
1419    }
1420
1421    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
1422    /// to be increased by chunks of size 64. The data is written to flash
1423    /// every 4 chunks (which equals to one page of size 256).
1424    ///
1425    /// This function is used by Brick Viewer during flashing. It should not be
1426    /// necessary to call it in a normal user program.
1427    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
1428        let mut payload = [0; 4];
1429        pointer.write_to_slice(&mut payload[0..4]);
1430
1431        #[allow(unused_variables)]
1432        let result = self.device.set(u8::from(NfcBrickletFunction::SetWriteFirmwarePointer), &payload).await?;
1433        Ok(())
1434    }
1435
1436    /// Writes 64 Bytes of firmware at the position as written by
1437    /// [`set_write_firmware_pointer`] before. The firmware is written
1438    /// to flash every 4 chunks.
1439    ///
1440    /// You can only write firmware in bootloader mode.
1441    ///
1442    /// This function is used by Brick Viewer during flashing. It should not be
1443    /// necessary to call it in a normal user program.
1444    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
1445        let mut payload = [0; 64];
1446        data.write_to_slice(&mut payload[0..64]);
1447
1448        #[allow(unused_variables)]
1449        let result = self.device.get(u8::from(NfcBrickletFunction::WriteFirmware), &payload).await?;
1450        Ok(u8::from_le_byte_slice(result.body()))
1451    }
1452
1453    /// Sets the status LED configuration. By default the LED shows
1454    /// communication traffic between Brick and Bricklet, it flickers once
1455    /// for every 10 received data packets.
1456    ///
1457    /// You can also turn the LED permanently on/off or show a heartbeat.
1458    ///
1459    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
1460    ///
1461    /// Associated constants:
1462    /// * NFC_BRICKLET_STATUS_LED_CONFIG_OFF
1463    ///	* NFC_BRICKLET_STATUS_LED_CONFIG_ON
1464    ///	* NFC_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
1465    ///	* NFC_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
1466    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
1467        let mut payload = [0; 1];
1468        config.write_to_slice(&mut payload[0..1]);
1469
1470        #[allow(unused_variables)]
1471        let result = self.device.set(u8::from(NfcBrickletFunction::SetStatusLedConfig), &payload).await?;
1472        Ok(())
1473    }
1474
1475    /// Returns the configuration as set by [`set_status_led_config`]
1476    ///
1477    /// Associated constants:
1478    /// * NFC_BRICKLET_STATUS_LED_CONFIG_OFF
1479    ///	* NFC_BRICKLET_STATUS_LED_CONFIG_ON
1480    ///	* NFC_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
1481    ///	* NFC_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
1482    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
1483        let payload = [0; 0];
1484
1485        #[allow(unused_variables)]
1486        let result = self.device.get(u8::from(NfcBrickletFunction::GetStatusLedConfig), &payload).await?;
1487        Ok(u8::from_le_byte_slice(result.body()))
1488    }
1489
1490    /// Returns the temperature as measured inside the microcontroller. The
1491    /// value returned is not the ambient temperature!
1492    ///
1493    /// The temperature is only proportional to the real temperature and it has bad
1494    /// accuracy. Practically it is only useful as an indicator for
1495    /// temperature changes.
1496    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
1497        let payload = [0; 0];
1498
1499        #[allow(unused_variables)]
1500        let result = self.device.get(u8::from(NfcBrickletFunction::GetChipTemperature), &payload).await?;
1501        Ok(i16::from_le_byte_slice(result.body()))
1502    }
1503
1504    /// Calling this function will reset the Bricklet. All configurations
1505    /// will be lost.
1506    ///
1507    /// After a reset you have to create new device objects,
1508    /// calling functions on the existing ones will result in
1509    /// undefined behavior!
1510    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
1511        let payload = [0; 0];
1512
1513        #[allow(unused_variables)]
1514        let result = self.device.set(u8::from(NfcBrickletFunction::Reset), &payload).await?;
1515        Ok(())
1516    }
1517
1518    /// Writes a new UID into flash. If you want to set a new UID
1519    /// you have to decode the Base58 encoded UID string into an
1520    /// integer first.
1521    ///
1522    /// We recommend that you use Brick Viewer to change the UID.
1523    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
1524        let mut payload = [0; 4];
1525        uid.write_to_slice(&mut payload[0..4]);
1526
1527        #[allow(unused_variables)]
1528        let result = self.device.set(u8::from(NfcBrickletFunction::WriteUid), &payload).await?;
1529        Ok(())
1530    }
1531
1532    /// Returns the current UID as an integer. Encode as
1533    /// Base58 to get the usual string version.
1534    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
1535        let payload = [0; 0];
1536
1537        #[allow(unused_variables)]
1538        let result = self.device.get(u8::from(NfcBrickletFunction::ReadUid), &payload).await?;
1539        Ok(u32::from_le_byte_slice(result.body()))
1540    }
1541
1542    /// Returns the UID, the UID where the Bricklet is connected to,
1543    /// the position, the hardware and firmware version as well as the
1544    /// device identifier.
1545    ///
1546    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
1547    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
1548    /// position 'z'.
1549    ///
1550    /// The device identifier numbers can be found [here](device_identifier).
1551    /// |device_identifier_constant|
1552    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
1553        let payload = [0; 0];
1554
1555        #[allow(unused_variables)]
1556        let result = self.device.get(u8::from(NfcBrickletFunction::GetIdentity), &payload).await?;
1557        Ok(Identity::from_le_byte_slice(result.body()))
1558    }
1559}