Skip to main content

freefare_sys/
lib.rs

1#![doc = include_str!("../README.md")]
2#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
3
4use core::ffi::{c_char, c_int, c_void};
5use libc::off_t;
6use nfc_sys::{nfc_device, nfc_iso14443a_info};
7
8#[repr(C)]
9#[derive(Debug, Copy, Clone, PartialEq, Eq)]
10pub enum FreefareTagType {
11    ULTRALIGHT = 0,
12    ULTRALIGHT_C = 1,
13    CLASSIC_1K = 2,
14    CLASSIC_4K = 3,
15    DESFIRE = 4,
16}
17
18#[repr(C)]
19pub struct mifare_tag {
20    _private: [u8; 0],
21}
22
23pub type MifareTag = *mut mifare_tag;
24pub type FreefareTag = MifareTag;
25
26#[repr(C)]
27pub struct mifare_desfire_key {
28    _private: [u8; 0],
29}
30
31pub type MifareDESFireKey = *mut mifare_desfire_key;
32
33pub type MifareUltralightPageNumber = u8;
34pub type MifareUltralightPage = [u8; 4];
35pub type MifareClassicBlock = [u8; 16];
36pub type MifareClassicSectorNumber = u8;
37pub type MifareClassicBlockNumber = u8;
38pub type MifareClassicKey = [u8; 6];
39
40#[repr(C)]
41#[derive(Debug, Copy, Clone, PartialEq, Eq)]
42pub enum MifareClassicKeyType {
43    MFC_KEY_A = 0,
44    MFC_KEY_B = 1,
45}
46
47#[repr(C)]
48#[derive(Debug, Copy, Clone, PartialEq, Eq)]
49pub struct MadAid {
50    pub application_code: u8,
51    pub function_cluster_code: u8,
52}
53
54#[repr(C)]
55pub struct mad {
56    _private: [u8; 0],
57}
58
59pub type Mad = *mut mad;
60
61#[repr(C)]
62#[derive(Debug, Copy, Clone, PartialEq, Eq)]
63pub enum MifareDesfireFileType {
64    MDFT_STANDARD_DATA_FILE = 0x00,
65    MDFT_BACKUP_DATA_FILE = 0x01,
66    MDFT_VALUE_FILE_WITH_BACKUP = 0x02,
67    MDFT_LINEAR_RECORD_FILE_WITH_BACKUP = 0x03,
68    MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP = 0x04,
69}
70
71#[repr(C)]
72pub struct mifare_desfire_aid {
73    _private: [u8; 0],
74}
75
76pub type MifareDESFireAID = *mut mifare_desfire_aid;
77
78#[repr(C)]
79#[derive(Debug, Copy, Clone)]
80pub struct MifareDESFireDF {
81    pub aid: u32,
82    pub fid: u16,
83    pub df_name: [u8; 16],
84    pub df_name_len: usize,
85}
86
87#[repr(C, packed)]
88#[derive(Debug, Copy, Clone, PartialEq, Eq)]
89pub struct MifareDESFireVersionComponent {
90    pub vendor_id: u8,
91    pub type_: u8,
92    pub subtype: u8,
93    pub version_major: u8,
94    pub version_minor: u8,
95    pub storage_size: u8,
96    pub protocol: u8,
97}
98
99#[repr(C, packed)]
100#[derive(Debug, Copy, Clone, PartialEq, Eq)]
101pub struct MifareDESFireVersionInfo {
102    pub hardware: MifareDESFireVersionComponent,
103    pub software: MifareDESFireVersionComponent,
104    pub uid: [u8; 7],
105    pub batch_number: [u8; 5],
106    pub production_week: u8,
107    pub production_year: u8,
108}
109
110#[repr(C)]
111#[derive(Copy, Clone)]
112pub union MifareDESFireFileSettingsData {
113    pub standard_file: MifareDESFireStandardFileSettings,
114    pub value_file: MifareDESFireValueFileSettings,
115    pub linear_record_file: MifareDESFireRecordFileSettings,
116}
117
118#[repr(C)]
119#[derive(Copy, Clone)]
120pub struct MifareDESFireFileSettings {
121    pub file_type: u8,
122    pub communication_settings: u8,
123    pub access_rights: u16,
124    pub settings: MifareDESFireFileSettingsData,
125}
126
127#[repr(C)]
128#[derive(Debug, Copy, Clone, PartialEq, Eq)]
129pub struct MifareDESFireStandardFileSettings {
130    pub file_size: u32,
131}
132
133#[repr(C)]
134#[derive(Debug, Copy, Clone, PartialEq, Eq)]
135pub struct MifareDESFireValueFileSettings {
136    pub lower_limit: i32,
137    pub upper_limit: i32,
138    pub limited_credit_value: i32,
139    pub limited_credit_enabled: u8,
140}
141
142#[repr(C)]
143#[derive(Debug, Copy, Clone, PartialEq, Eq)]
144pub struct MifareDESFireRecordFileSettings {
145    pub record_size: u32,
146    pub max_number_of_records: u32,
147    pub current_number_of_records: u32,
148}
149
150pub const C_000: u32 = 0;
151pub const C_001: u32 = 1;
152pub const C_010: u32 = 2;
153pub const C_011: u32 = 3;
154pub const C_100: u32 = 4;
155pub const C_101: u32 = 5;
156pub const C_110: u32 = 6;
157pub const C_111: u32 = 7;
158pub const C_DEFAULT: u32 = 255;
159
160pub const MCAB_R: u32 = 0x8;
161pub const MCAB_W: u32 = 0x4;
162pub const MCAB_D: u32 = 0x2;
163pub const MCAB_I: u32 = 0x1;
164
165pub const MCAB_READ_KEYA: u32 = 0x400;
166pub const MCAB_WRITE_KEYA: u32 = 0x100;
167pub const MCAB_READ_ACCESS_BITS: u32 = 0x040;
168pub const MCAB_WRITE_ACCESS_BITS: u32 = 0x010;
169pub const MCAB_READ_KEYB: u32 = 0x004;
170pub const MCAB_WRITE_KEYB: u32 = 0x001;
171
172pub const MDCM_PLAIN: u32 = 0x00;
173pub const MDCM_MACED: u32 = 0x01;
174pub const MDCM_ENCIPHERED: u32 = 0x03;
175
176pub const APPLICATION_CRYPTO_DES: u32 = 0x00;
177pub const APPLICATION_CRYPTO_3K3DES: u32 = 0x40;
178pub const APPLICATION_CRYPTO_AES: u32 = 0x80;
179
180pub const MDAR_KEY0: u16 = 0x0;
181pub const MDAR_KEY1: u16 = 0x1;
182pub const MDAR_KEY2: u16 = 0x2;
183pub const MDAR_KEY3: u16 = 0x3;
184pub const MDAR_KEY4: u16 = 0x4;
185pub const MDAR_KEY5: u16 = 0x5;
186pub const MDAR_KEY6: u16 = 0x6;
187pub const MDAR_KEY7: u16 = 0x7;
188pub const MDAR_KEY8: u16 = 0x8;
189pub const MDAR_KEY9: u16 = 0x9;
190pub const MDAR_KEY10: u16 = 0xa;
191pub const MDAR_KEY11: u16 = 0xb;
192pub const MDAR_KEY12: u16 = 0xc;
193pub const MDAR_KEY13: u16 = 0xd;
194pub const MDAR_FREE: u16 = 0xE;
195pub const MDAR_DENY: u16 = 0xF;
196
197pub const OPERATION_OK: u8 = 0x00;
198pub const NO_CHANGES: u8 = 0x0C;
199pub const OUT_OF_EEPROM_ERROR: u8 = 0x0E;
200pub const ILLEGAL_COMMAND_CODE: u8 = 0x1C;
201pub const INTEGRITY_ERROR: u8 = 0x1E;
202pub const NO_SUCH_KEY: u8 = 0x40;
203pub const LENGTH_ERROR: u8 = 0x7E;
204pub const PERMISSION_ERROR: u8 = 0x9D;
205pub const PARAMETER_ERROR: u8 = 0x9E;
206pub const APPLICATION_NOT_FOUND: u8 = 0xA0;
207pub const APPL_INTEGRITY_ERROR: u8 = 0xA1;
208pub const AUTHENTICATION_ERROR: u8 = 0xAE;
209pub const ADDITIONAL_FRAME: u8 = 0xAF;
210pub const BOUNDARY_ERROR: u8 = 0xBE;
211pub const PICC_INTEGRITY_ERROR: u8 = 0xC1;
212pub const COMMAND_ABORTED: u8 = 0xCA;
213pub const PICC_DISABLED_ERROR: u8 = 0xCD;
214pub const COUNT_ERROR: u8 = 0xCE;
215pub const DUPLICATE_ERROR: u8 = 0xDE;
216pub const EEPROM_ERROR: u8 = 0xEE;
217pub const FILE_NOT_FOUND: u8 = 0xF0;
218pub const FILE_INTEGRITY_ERROR: u8 = 0xF1;
219pub const CRYPTO_ERROR: u8 = 0x01;
220
221pub const fn mdar(read: u16, write: u16, read_write: u16, change_access_rights: u16) -> u16 {
222    (read << 12) | (write << 8) | (read_write << 4) | change_access_rights
223}
224
225pub const fn mdar_read(access_rights: u16) -> u16 {
226    (access_rights >> 12) & 0x0f
227}
228
229pub const fn mdar_write(access_rights: u16) -> u16 {
230    (access_rights >> 8) & 0x0f
231}
232
233pub const fn mdar_read_write(access_rights: u16) -> u16 {
234    (access_rights >> 4) & 0x0f
235}
236
237pub const fn mdar_change_ar(access_rights: u16) -> u16 {
238    access_rights & 0x0f
239}
240
241unsafe extern "C" {
242    pub static mifare_classic_nfcforum_public_key_a: MifareClassicKey;
243    pub static mad_public_key_a: MifareClassicKey;
244    pub static mad_free_aid: MadAid;
245    pub static mad_defect_aid: MadAid;
246    pub static mad_reserved_aid: MadAid;
247    pub static mad_card_holder_aid: MadAid;
248    pub static mad_not_applicable_aid: MadAid;
249    pub static mad_nfcforum_aid: MadAid;
250
251    pub fn freefare_get_tags(device: *mut nfc_device) -> *mut MifareTag;
252    pub fn freefare_tag_new(device: *mut nfc_device, nai: nfc_iso14443a_info) -> MifareTag;
253    pub fn freefare_get_tag_type(tag: MifareTag) -> FreefareTagType;
254    pub fn freefare_get_tag_friendly_name(tag: MifareTag) -> *const c_char;
255    pub fn freefare_get_tag_uid(tag: MifareTag) -> *mut c_char;
256    pub fn freefare_free_tag(tag: MifareTag);
257    pub fn freefare_free_tags(tags: *mut MifareTag);
258
259    pub fn freefare_strerror(tag: MifareTag) -> *const c_char;
260    pub fn freefare_strerror_r(tag: MifareTag, buffer: *mut c_char, len: usize) -> c_int;
261    pub fn freefare_perror(tag: MifareTag, string: *const c_char);
262
263    pub fn mifare_ultralight_connect(tag: MifareTag) -> c_int;
264    pub fn mifare_ultralight_disconnect(tag: MifareTag) -> c_int;
265    pub fn mifare_ultralight_read(
266        tag: MifareTag,
267        page: MifareUltralightPageNumber,
268        data: *mut MifareUltralightPage,
269    ) -> c_int;
270    pub fn mifare_ultralight_write(
271        tag: MifareTag,
272        page: MifareUltralightPageNumber,
273        data: *const MifareUltralightPage,
274    ) -> c_int;
275    pub fn mifare_ultralightc_authenticate(tag: MifareTag, key: MifareDESFireKey) -> c_int;
276    pub fn is_mifare_ultralightc_on_reader(
277        device: *mut nfc_device,
278        nai: nfc_iso14443a_info,
279    ) -> bool;
280
281    pub fn mifare_classic_connect(tag: MifareTag) -> c_int;
282    pub fn mifare_classic_disconnect(tag: MifareTag) -> c_int;
283    pub fn mifare_classic_authenticate(
284        tag: MifareTag,
285        block: MifareClassicBlockNumber,
286        key: *const MifareClassicKey,
287        key_type: MifareClassicKeyType,
288    ) -> c_int;
289    pub fn mifare_classic_read(
290        tag: MifareTag,
291        block: MifareClassicBlockNumber,
292        data: *mut MifareClassicBlock,
293    ) -> c_int;
294    pub fn mifare_classic_init_value(
295        tag: MifareTag,
296        block: MifareClassicBlockNumber,
297        value: i32,
298        adr: MifareClassicBlockNumber,
299    ) -> c_int;
300    pub fn mifare_classic_read_value(
301        tag: MifareTag,
302        block: MifareClassicBlockNumber,
303        value: *mut i32,
304        adr: *mut MifareClassicBlockNumber,
305    ) -> c_int;
306    pub fn mifare_classic_write(
307        tag: MifareTag,
308        block: MifareClassicBlockNumber,
309        data: *const MifareClassicBlock,
310    ) -> c_int;
311    pub fn mifare_classic_increment(
312        tag: MifareTag,
313        block: MifareClassicBlockNumber,
314        amount: u32,
315    ) -> c_int;
316    pub fn mifare_classic_decrement(
317        tag: MifareTag,
318        block: MifareClassicBlockNumber,
319        amount: u32,
320    ) -> c_int;
321    pub fn mifare_classic_restore(tag: MifareTag, block: MifareClassicBlockNumber) -> c_int;
322    pub fn mifare_classic_transfer(tag: MifareTag, block: MifareClassicBlockNumber) -> c_int;
323    pub fn mifare_classic_get_trailer_block_permission(
324        tag: MifareTag,
325        block: MifareClassicBlockNumber,
326        permission: u16,
327        key_type: MifareClassicKeyType,
328    ) -> c_int;
329    pub fn mifare_classic_get_data_block_permission(
330        tag: MifareTag,
331        block: MifareClassicBlockNumber,
332        permission: u8,
333        key_type: MifareClassicKeyType,
334    ) -> c_int;
335    pub fn mifare_classic_format_sector(tag: MifareTag, sector: MifareClassicSectorNumber)
336        -> c_int;
337    pub fn mifare_classic_trailer_block(
338        block: *mut MifareClassicBlock,
339        key_a: *const MifareClassicKey,
340        ab_0: u8,
341        ab_1: u8,
342        ab_2: u8,
343        ab_tb: u8,
344        gpb: u8,
345        key_b: *const MifareClassicKey,
346    );
347    pub fn mifare_classic_block_sector(
348        block: MifareClassicBlockNumber,
349    ) -> MifareClassicSectorNumber;
350    pub fn mifare_classic_sector_first_block(
351        sector: MifareClassicSectorNumber,
352    ) -> MifareClassicBlockNumber;
353    pub fn mifare_classic_sector_block_count(sector: MifareClassicSectorNumber) -> usize;
354    pub fn mifare_classic_sector_last_block(
355        sector: MifareClassicSectorNumber,
356    ) -> MifareClassicBlockNumber;
357
358    pub fn mad_new(version: u8) -> Mad;
359    pub fn mad_read(tag: MifareTag) -> Mad;
360    pub fn mad_write(
361        tag: MifareTag,
362        mad: Mad,
363        key_b_sector_00: *const MifareClassicKey,
364        key_b_sector_10: *const MifareClassicKey,
365    ) -> c_int;
366    pub fn mad_get_version(mad: Mad) -> c_int;
367    pub fn mad_set_version(mad: Mad, version: u8);
368    pub fn mad_get_card_publisher_sector(mad: Mad) -> MifareClassicSectorNumber;
369    pub fn mad_set_card_publisher_sector(mad: Mad, cps: MifareClassicSectorNumber) -> c_int;
370    pub fn mad_get_aid(mad: Mad, sector: MifareClassicSectorNumber, aid: *mut MadAid) -> c_int;
371    pub fn mad_set_aid(mad: Mad, sector: MifareClassicSectorNumber, aid: MadAid) -> c_int;
372    pub fn mad_sector_reserved(sector: MifareClassicSectorNumber) -> bool;
373    pub fn mad_free(mad: Mad);
374
375    pub fn mifare_application_alloc(
376        mad: Mad,
377        aid: MadAid,
378        size: usize,
379    ) -> *mut MifareClassicSectorNumber;
380    pub fn mifare_application_read(
381        tag: MifareTag,
382        mad: Mad,
383        aid: MadAid,
384        buf: *mut c_void,
385        nbytes: usize,
386        key: *const MifareClassicKey,
387        key_type: MifareClassicKeyType,
388    ) -> isize;
389    pub fn mifare_application_write(
390        tag: MifareTag,
391        mad: Mad,
392        aid: MadAid,
393        buf: *const c_void,
394        nbytes: usize,
395        key: *const MifareClassicKey,
396        key_type: MifareClassicKeyType,
397    ) -> isize;
398    pub fn mifare_application_free(mad: Mad, aid: MadAid);
399    pub fn mifare_application_find(mad: Mad, aid: MadAid) -> *mut MifareClassicSectorNumber;
400
401    pub fn mifare_desfire_aid_new(aid: u32) -> MifareDESFireAID;
402    pub fn mifare_desfire_aid_new_with_mad_aid(mad_aid: MadAid, n: u8) -> MifareDESFireAID;
403    pub fn mifare_desfire_aid_get_aid(aid: MifareDESFireAID) -> u32;
404    pub fn mifare_desfire_last_pcd_error(tag: MifareTag) -> u8;
405    pub fn mifare_desfire_last_picc_error(tag: MifareTag) -> u8;
406    pub fn mifare_desfire_connect(tag: MifareTag) -> c_int;
407    pub fn mifare_desfire_disconnect(tag: MifareTag) -> c_int;
408    pub fn mifare_desfire_authenticate(tag: MifareTag, key_no: u8, key: MifareDESFireKey) -> c_int;
409    pub fn mifare_desfire_authenticate_iso(
410        tag: MifareTag,
411        key_no: u8,
412        key: MifareDESFireKey,
413    ) -> c_int;
414    pub fn mifare_desfire_authenticate_aes(
415        tag: MifareTag,
416        key_no: u8,
417        key: MifareDESFireKey,
418    ) -> c_int;
419    pub fn mifare_desfire_change_key_settings(tag: MifareTag, settings: u8) -> c_int;
420    pub fn mifare_desfire_get_key_settings(
421        tag: MifareTag,
422        settings: *mut u8,
423        max_keys: *mut u8,
424    ) -> c_int;
425    pub fn mifare_desfire_change_key(
426        tag: MifareTag,
427        key_no: u8,
428        new_key: MifareDESFireKey,
429        old_key: MifareDESFireKey,
430    ) -> c_int;
431    pub fn mifare_desfire_get_key_version(tag: MifareTag, key_no: u8, version: *mut u8) -> c_int;
432    pub fn mifare_desfire_create_application(
433        tag: MifareTag,
434        aid: MifareDESFireAID,
435        settings: u8,
436        key_no: u8,
437    ) -> c_int;
438    pub fn mifare_desfire_create_application_3k3des(
439        tag: MifareTag,
440        aid: MifareDESFireAID,
441        settings: u8,
442        key_no: u8,
443    ) -> c_int;
444    pub fn mifare_desfire_create_application_aes(
445        tag: MifareTag,
446        aid: MifareDESFireAID,
447        settings: u8,
448        key_no: u8,
449    ) -> c_int;
450    pub fn mifare_desfire_create_application_iso(
451        tag: MifareTag,
452        aid: MifareDESFireAID,
453        settings: u8,
454        key_no: u8,
455        want_iso_file_identifiers: c_int,
456        iso_file_id: u16,
457        iso_file_name: *mut u8,
458        iso_file_name_len: usize,
459    ) -> c_int;
460    pub fn mifare_desfire_create_application_3k3des_iso(
461        tag: MifareTag,
462        aid: MifareDESFireAID,
463        settings: u8,
464        key_no: u8,
465        want_iso_file_identifiers: c_int,
466        iso_file_id: u16,
467        iso_file_name: *mut u8,
468        iso_file_name_len: usize,
469    ) -> c_int;
470    pub fn mifare_desfire_create_application_aes_iso(
471        tag: MifareTag,
472        aid: MifareDESFireAID,
473        settings: u8,
474        key_no: u8,
475        want_iso_file_identifiers: c_int,
476        iso_file_id: u16,
477        iso_file_name: *mut u8,
478        iso_file_name_len: usize,
479    ) -> c_int;
480    pub fn mifare_desfire_delete_application(tag: MifareTag, aid: MifareDESFireAID) -> c_int;
481    pub fn mifare_desfire_get_application_ids(
482        tag: MifareTag,
483        aids: *mut *mut MifareDESFireAID,
484        count: *mut usize,
485    ) -> c_int;
486    pub fn mifare_desfire_get_df_names(
487        tag: MifareTag,
488        dfs: *mut *mut MifareDESFireDF,
489        count: *mut usize,
490    ) -> c_int;
491    pub fn mifare_desfire_free_application_ids(aids: *mut MifareDESFireAID);
492    pub fn mifare_desfire_select_application(tag: MifareTag, aid: MifareDESFireAID) -> c_int;
493    pub fn mifare_desfire_format_picc(tag: MifareTag) -> c_int;
494    pub fn mifare_desfire_get_version(
495        tag: MifareTag,
496        version_info: *mut MifareDESFireVersionInfo,
497    ) -> c_int;
498    pub fn mifare_desfire_free_mem(tag: MifareTag, size: *mut u32) -> c_int;
499    pub fn mifare_desfire_set_configuration(
500        tag: MifareTag,
501        disable_format: bool,
502        enable_random_uid: bool,
503    ) -> c_int;
504    pub fn mifare_desfire_set_default_key(tag: MifareTag, key: MifareDESFireKey) -> c_int;
505    pub fn mifare_desfire_set_ats(tag: MifareTag, ats: *mut u8) -> c_int;
506    pub fn mifare_desfire_get_card_uid(tag: MifareTag, uid: *mut *mut c_char) -> c_int;
507    pub fn mifare_desfire_get_file_ids(
508        tag: MifareTag,
509        files: *mut *mut u8,
510        count: *mut usize,
511    ) -> c_int;
512    pub fn mifare_desfire_get_iso_file_ids(
513        tag: MifareTag,
514        files: *mut *mut u16,
515        count: *mut usize,
516    ) -> c_int;
517    pub fn mifare_desfire_get_file_settings(
518        tag: MifareTag,
519        file_no: u8,
520        settings: *mut MifareDESFireFileSettings,
521    ) -> c_int;
522    pub fn mifare_desfire_change_file_settings(
523        tag: MifareTag,
524        file_no: u8,
525        communication_settings: u8,
526        access_rights: u16,
527    ) -> c_int;
528    pub fn mifare_desfire_create_std_data_file(
529        tag: MifareTag,
530        file_no: u8,
531        communication_settings: u8,
532        access_rights: u16,
533        file_size: u32,
534    ) -> c_int;
535    pub fn mifare_desfire_create_std_data_file_iso(
536        tag: MifareTag,
537        file_no: u8,
538        communication_settings: u8,
539        access_rights: u16,
540        file_size: u32,
541        iso_file_id: u16,
542    ) -> c_int;
543    pub fn mifare_desfire_create_backup_data_file(
544        tag: MifareTag,
545        file_no: u8,
546        communication_settings: u8,
547        access_rights: u16,
548        file_size: u32,
549    ) -> c_int;
550    pub fn mifare_desfire_create_backup_data_file_iso(
551        tag: MifareTag,
552        file_no: u8,
553        communication_settings: u8,
554        access_rights: u16,
555        file_size: u32,
556        iso_file_id: u16,
557    ) -> c_int;
558    pub fn mifare_desfire_create_value_file(
559        tag: MifareTag,
560        file_no: u8,
561        communication_settings: u8,
562        access_rights: u16,
563        lower_limit: i32,
564        upper_limit: i32,
565        value: i32,
566        limited_credit_enable: u8,
567    ) -> c_int;
568    pub fn mifare_desfire_create_linear_record_file(
569        tag: MifareTag,
570        file_no: u8,
571        communication_settings: u8,
572        access_rights: u16,
573        record_size: u32,
574        max_number_of_records: u32,
575    ) -> c_int;
576    pub fn mifare_desfire_create_linear_record_file_iso(
577        tag: MifareTag,
578        file_no: u8,
579        communication_settings: u8,
580        access_rights: u16,
581        record_size: u32,
582        max_number_of_records: u32,
583        iso_file_id: u16,
584    ) -> c_int;
585    pub fn mifare_desfire_create_cyclic_record_file(
586        tag: MifareTag,
587        file_no: u8,
588        communication_settings: u8,
589        access_rights: u16,
590        record_size: u32,
591        max_number_of_records: u32,
592    ) -> c_int;
593    pub fn mifare_desfire_create_cyclic_record_file_iso(
594        tag: MifareTag,
595        file_no: u8,
596        communication_settings: u8,
597        access_rights: u16,
598        record_size: u32,
599        max_number_of_records: u32,
600        iso_file_id: u16,
601    ) -> c_int;
602    pub fn mifare_desfire_delete_file(tag: MifareTag, file_no: u8) -> c_int;
603    pub fn mifare_desfire_read_data(
604        tag: MifareTag,
605        file_no: u8,
606        offset: off_t,
607        length: usize,
608        data: *mut c_void,
609    ) -> isize;
610    pub fn mifare_desfire_read_data_ex(
611        tag: MifareTag,
612        file_no: u8,
613        offset: off_t,
614        length: usize,
615        data: *mut c_void,
616        cs: c_int,
617    ) -> isize;
618    pub fn mifare_desfire_write_data(
619        tag: MifareTag,
620        file_no: u8,
621        offset: off_t,
622        length: usize,
623        data: *const c_void,
624    ) -> isize;
625    pub fn mifare_desfire_write_data_ex(
626        tag: MifareTag,
627        file_no: u8,
628        offset: off_t,
629        length: usize,
630        data: *const c_void,
631        cs: c_int,
632    ) -> isize;
633    pub fn mifare_desfire_get_value(tag: MifareTag, file_no: u8, value: *mut i32) -> c_int;
634    pub fn mifare_desfire_get_value_ex(
635        tag: MifareTag,
636        file_no: u8,
637        value: *mut i32,
638        cs: c_int,
639    ) -> c_int;
640    pub fn mifare_desfire_credit(tag: MifareTag, file_no: u8, amount: i32) -> c_int;
641    pub fn mifare_desfire_credit_ex(tag: MifareTag, file_no: u8, amount: i32, cs: c_int) -> c_int;
642    pub fn mifare_desfire_debit(tag: MifareTag, file_no: u8, amount: i32) -> c_int;
643    pub fn mifare_desfire_debit_ex(tag: MifareTag, file_no: u8, amount: i32, cs: c_int) -> c_int;
644    pub fn mifare_desfire_limited_credit(tag: MifareTag, file_no: u8, amount: i32) -> c_int;
645    pub fn mifare_desfire_limited_credit_ex(
646        tag: MifareTag,
647        file_no: u8,
648        amount: i32,
649        cs: c_int,
650    ) -> c_int;
651    pub fn mifare_desfire_write_record(
652        tag: MifareTag,
653        file_no: u8,
654        offset: off_t,
655        length: usize,
656        data: *mut c_void,
657    ) -> isize;
658    pub fn mifare_desfire_write_record_ex(
659        tag: MifareTag,
660        file_no: u8,
661        offset: off_t,
662        length: usize,
663        data: *mut c_void,
664        cs: c_int,
665    ) -> isize;
666    pub fn mifare_desfire_read_records(
667        tag: MifareTag,
668        file_no: u8,
669        offset: off_t,
670        length: usize,
671        data: *mut c_void,
672    ) -> isize;
673    pub fn mifare_desfire_read_records_ex(
674        tag: MifareTag,
675        file_no: u8,
676        offset: off_t,
677        length: usize,
678        data: *mut c_void,
679        cs: c_int,
680    ) -> isize;
681    pub fn mifare_desfire_clear_record_file(tag: MifareTag, file_no: u8) -> c_int;
682    pub fn mifare_desfire_commit_transaction(tag: MifareTag) -> c_int;
683    pub fn mifare_desfire_abort_transaction(tag: MifareTag) -> c_int;
684    pub fn mifare_desfire_des_key_new(value: *mut u8) -> MifareDESFireKey;
685    pub fn mifare_desfire_3des_key_new(value: *mut u8) -> MifareDESFireKey;
686    pub fn mifare_desfire_des_key_new_with_version(value: *mut u8) -> MifareDESFireKey;
687    pub fn mifare_desfire_3des_key_new_with_version(value: *mut u8) -> MifareDESFireKey;
688    pub fn mifare_desfire_3k3des_key_new(value: *mut u8) -> MifareDESFireKey;
689    pub fn mifare_desfire_3k3des_key_new_with_version(value: *mut u8) -> MifareDESFireKey;
690    pub fn mifare_desfire_aes_key_new(value: *mut u8) -> MifareDESFireKey;
691    pub fn mifare_desfire_aes_key_new_with_version(value: *mut u8, version: u8)
692        -> MifareDESFireKey;
693    pub fn mifare_desfire_key_get_version(key: MifareDESFireKey) -> u8;
694    pub fn mifare_desfire_key_set_version(key: MifareDESFireKey, version: u8);
695    pub fn mifare_desfire_key_free(key: MifareDESFireKey);
696
697    pub fn tlv_encode(_type: u8, istream: *const u8, isize: u16, osize: *mut usize) -> *mut u8;
698    pub fn tlv_decode(istream: *const u8, _type: *mut u8, size: *mut u16) -> *mut u8;
699    pub fn tlv_record_length(
700        istream: *const u8,
701        field_length_size: *mut usize,
702        field_value_size: *mut usize,
703    ) -> usize;
704    pub fn tlv_append(a: *mut u8, b: *mut u8) -> *mut u8;
705}
706
707#[cfg(test)]
708mod tests {
709    use super::*;
710
711    #[test]
712    fn packed_and_layout_smoke_tests() {
713        assert_eq!(core::mem::size_of::<MadAid>(), 2);
714        assert_eq!(core::mem::size_of::<MifareDESFireVersionComponent>(), 7);
715        assert_eq!(core::mem::size_of::<MifareDESFireVersionInfo>(), 28);
716        assert_eq!(core::mem::size_of::<MifareDESFireFileSettings>(), 20);
717    }
718
719    #[test]
720    fn access_right_helpers_match_header_macros() {
721        let access_rights = mdar(MDAR_KEY1, MDAR_KEY2, MDAR_FREE, MDAR_DENY);
722        assert_eq!(mdar_read(access_rights), MDAR_KEY1);
723        assert_eq!(mdar_write(access_rights), MDAR_KEY2);
724        assert_eq!(mdar_read_write(access_rights), MDAR_FREE);
725        assert_eq!(mdar_change_ar(access_rights), MDAR_DENY);
726    }
727
728    #[test]
729    fn links_against_system_libraries() {
730        let version = unsafe { nfc_sys::nfc_version() };
731        assert!(!version.is_null());
732    }
733}