1#![allow(non_camel_case_types, non_snake_case)]
2extern crate libc;
41
42use libc::{c_char, c_int, c_void, size_t};
43
44pub const NFC_BUFSIZE_CONNSTRING: usize = 1024;
45
46pub const NFC_SUCCESS: c_int = 0;
47pub const NFC_EIO: c_int = -1;
48pub const NFC_EINVARG: c_int = -2;
49pub const NFC_EDEVNOTSUPP: c_int = -3;
50pub const NFC_ENOTSUCHDEV: c_int = -4;
51pub const NFC_EOVFLOW: c_int = -5;
52pub const NFC_ETIMEOUT: c_int = -6;
53pub const NFC_EOPABORTED: c_int = -7;
54pub const NFC_ENOTIMPL: c_int = -8;
55pub const NFC_ETGRELEASED: c_int = -10;
56pub const NFC_ERFTRANS: c_int = -20;
57pub const NFC_EMFCAUTHFAIL: c_int = -30;
58pub const NFC_ESOFT: c_int = -80;
59pub const NFC_ECHIP: c_int = -90;
60
61#[repr(C)]
63pub struct nfc_context {
64 _private: [u8; 0],
65}
66
67#[repr(C)]
69pub struct nfc_device {
70 _private: [u8; 0],
71}
72
73#[repr(C)]
75pub struct nfc_driver {
76 _private: [u8; 0],
77}
78
79pub type nfc_connstring = [c_char; NFC_BUFSIZE_CONNSTRING];
80
81#[repr(C)]
82#[derive(Copy, Clone, Debug, Eq, PartialEq)]
83pub enum nfc_property {
84 NP_TIMEOUT_COMMAND = 0,
85 NP_TIMEOUT_ATR = 1,
86 NP_TIMEOUT_COM = 2,
87 NP_HANDLE_CRC = 3,
88 NP_HANDLE_PARITY = 4,
89 NP_ACTIVATE_FIELD = 5,
90 NP_ACTIVATE_CRYPTO1 = 6,
91 NP_INFINITE_SELECT = 7,
92 NP_ACCEPT_INVALID_FRAMES = 8,
93 NP_ACCEPT_MULTIPLE_FRAMES = 9,
94 NP_AUTO_ISO14443_4 = 10,
95 NP_EASY_FRAMING = 11,
96 NP_FORCE_ISO14443_A = 12,
97 NP_FORCE_ISO14443_B = 13,
98 NP_FORCE_SPEED_106 = 14,
99}
100
101#[repr(C)]
102#[derive(Copy, Clone, Debug, Eq, PartialEq)]
103pub enum nfc_dep_mode {
104 NDM_UNDEFINED = 0,
105 NDM_PASSIVE = 1,
106 NDM_ACTIVE = 2,
107}
108
109#[repr(C, packed)]
110#[derive(Copy, Clone)]
111pub struct nfc_dep_info {
112 pub abtNFCID3: [u8; 10],
113 pub btDID: u8,
114 pub btBS: u8,
115 pub btBR: u8,
116 pub btTO: u8,
117 pub btPP: u8,
118 pub abtGB: [u8; 48],
119 pub szGB: size_t,
120 pub ndm: nfc_dep_mode,
121}
122
123#[repr(C, packed)]
124#[derive(Copy, Clone)]
125pub struct nfc_iso14443a_info {
126 pub abtAtqa: [u8; 2],
127 pub btSak: u8,
128 pub szUidLen: size_t,
129 pub abtUid: [u8; 10],
130 pub szAtsLen: size_t,
131 pub abtAts: [u8; 254],
132}
133
134#[repr(C, packed)]
135#[derive(Copy, Clone)]
136pub struct nfc_felica_info {
137 pub szLen: size_t,
138 pub btResCode: u8,
139 pub abtId: [u8; 8],
140 pub abtPad: [u8; 8],
141 pub abtSysCode: [u8; 2],
142}
143
144#[repr(C, packed)]
145#[derive(Copy, Clone)]
146pub struct nfc_iso14443b_info {
147 pub abtPupi: [u8; 4],
148 pub abtApplicationData: [u8; 4],
149 pub abtProtocolInfo: [u8; 3],
150 pub ui8CardIdentifier: u8,
151}
152
153#[repr(C, packed)]
154#[derive(Copy, Clone)]
155pub struct nfc_iso14443bi_info {
156 pub abtDIV: [u8; 4],
157 pub btVerLog: u8,
158 pub btConfig: u8,
159 pub szAtrLen: size_t,
160 pub abtAtr: [u8; 33],
161}
162
163#[repr(C, packed)]
164#[derive(Copy, Clone)]
165pub struct nfc_iso14443biclass_info {
166 pub abtUID: [u8; 8],
167}
168
169#[repr(C, packed)]
170#[derive(Copy, Clone)]
171pub struct nfc_iso14443b2sr_info {
172 pub abtUID: [u8; 8],
173}
174
175#[repr(C, packed)]
176#[derive(Copy, Clone)]
177pub struct nfc_iso14443b2ct_info {
178 pub abtUID: [u8; 4],
179 pub btProdCode: u8,
180 pub btFabCode: u8,
181}
182
183#[repr(C, packed)]
184#[derive(Copy, Clone)]
185pub struct nfc_jewel_info {
186 pub btSensRes: [u8; 2],
187 pub btId: [u8; 4],
188}
189
190#[repr(C, packed)]
191#[derive(Copy, Clone)]
192pub struct nfc_barcode_info {
193 pub szDataLen: size_t,
194 pub abtData: [u8; 32],
195}
196
197#[repr(C, packed)]
198#[derive(Copy, Clone)]
199pub union nfc_target_info {
200 pub nai: nfc_iso14443a_info,
201 pub nfi: nfc_felica_info,
202 pub nbi: nfc_iso14443b_info,
203 pub nii: nfc_iso14443bi_info,
204 pub nsi: nfc_iso14443b2sr_info,
205 pub nci: nfc_iso14443b2ct_info,
206 pub nji: nfc_jewel_info,
207 pub ndi: nfc_dep_info,
208 pub nti: nfc_barcode_info,
209 pub nhi: nfc_iso14443biclass_info,
210}
211
212#[repr(C)]
213#[derive(Copy, Clone, Debug, Eq, PartialEq)]
214pub enum nfc_baud_rate {
215 NBR_UNDEFINED = 0,
216 NBR_106 = 1,
217 NBR_212 = 2,
218 NBR_424 = 3,
219 NBR_847 = 4,
220}
221
222#[repr(C)]
223#[derive(Copy, Clone, Debug, Eq, PartialEq)]
224pub enum nfc_modulation_type {
225 NMT_ISO14443A = 1,
226 NMT_JEWEL = 2,
227 NMT_ISO14443B = 3,
228 NMT_ISO14443BI = 4,
229 NMT_ISO14443B2SR = 5,
230 NMT_ISO14443B2CT = 6,
231 NMT_FELICA = 7,
232 NMT_DEP = 8,
233 NMT_BARCODE = 9,
234 NMT_ISO14443BICLASS = 10,
235}
236
237pub const NMT_END_ENUM: nfc_modulation_type = nfc_modulation_type::NMT_ISO14443BICLASS;
238
239#[repr(C)]
240#[derive(Copy, Clone, Debug, Eq, PartialEq)]
241pub enum nfc_mode {
242 N_TARGET = 0,
243 N_INITIATOR = 1,
244}
245
246#[repr(C, packed)]
247#[derive(Copy, Clone)]
248pub struct nfc_modulation {
249 pub nmt: nfc_modulation_type,
250 pub nbr: nfc_baud_rate,
251}
252
253#[repr(C, packed)]
254#[derive(Copy, Clone)]
255pub struct nfc_target {
256 pub nti: nfc_target_info,
257 pub nm: nfc_modulation,
258}
259
260#[repr(C)]
261pub struct nfc_emulator {
262 pub target: *mut nfc_target,
263 pub state_machine: *mut nfc_emulation_state_machine,
264 pub user_data: *mut c_void,
265}
266
267#[repr(C)]
268pub struct nfc_emulation_state_machine {
269 pub io: Option<
270 unsafe extern "C" fn(
271 emulator: *mut nfc_emulator,
272 data_in: *const u8,
273 data_in_len: size_t,
274 data_out: *mut u8,
275 data_out_len: size_t,
276 ) -> c_int,
277 >,
278 pub data: *mut c_void,
279}
280
281#[link(name = "nfc")]
282extern "C" {
283 pub fn nfc_init(context: *mut *mut nfc_context);
284 pub fn nfc_exit(context: *mut nfc_context);
285 pub fn nfc_register_driver(driver: *const nfc_driver) -> c_int;
286
287 pub fn nfc_open(context: *mut nfc_context, connstring: *const c_char) -> *mut nfc_device;
288 pub fn nfc_close(pnd: *mut nfc_device);
289 pub fn nfc_abort_command(pnd: *mut nfc_device) -> c_int;
290 pub fn nfc_list_devices(
291 context: *mut nfc_context,
292 connstrings: *mut nfc_connstring,
293 connstrings_len: size_t,
294 ) -> size_t;
295 pub fn nfc_idle(pnd: *mut nfc_device) -> c_int;
296
297 pub fn nfc_initiator_init(pnd: *mut nfc_device) -> c_int;
298 pub fn nfc_initiator_init_secure_element(pnd: *mut nfc_device) -> c_int;
299 pub fn nfc_initiator_select_passive_target(
300 pnd: *mut nfc_device,
301 nm: nfc_modulation,
302 pbtInitData: *const u8,
303 szInitData: size_t,
304 pnt: *mut nfc_target,
305 ) -> c_int;
306 pub fn nfc_initiator_list_passive_targets(
307 pnd: *mut nfc_device,
308 nm: nfc_modulation,
309 ant: *mut nfc_target,
310 szTargets: size_t,
311 ) -> c_int;
312 pub fn nfc_initiator_poll_target(
313 pnd: *mut nfc_device,
314 pnmTargetTypes: *const nfc_modulation,
315 szTargetTypes: size_t,
316 uiPollNr: u8,
317 uiPeriod: u8,
318 pnt: *mut nfc_target,
319 ) -> c_int;
320 pub fn nfc_initiator_select_dep_target(
321 pnd: *mut nfc_device,
322 ndm: nfc_dep_mode,
323 nbr: nfc_baud_rate,
324 pndiInitiator: *const nfc_dep_info,
325 pnt: *mut nfc_target,
326 timeout: c_int,
327 ) -> c_int;
328 pub fn nfc_initiator_poll_dep_target(
329 pnd: *mut nfc_device,
330 ndm: nfc_dep_mode,
331 nbr: nfc_baud_rate,
332 pndiInitiator: *const nfc_dep_info,
333 pnt: *mut nfc_target,
334 timeout: c_int,
335 ) -> c_int;
336 pub fn nfc_initiator_deselect_target(pnd: *mut nfc_device) -> c_int;
337 pub fn nfc_initiator_transceive_bytes(
338 pnd: *mut nfc_device,
339 pbtTx: *const u8,
340 szTx: size_t,
341 pbtRx: *mut u8,
342 szRx: size_t,
343 timeout: c_int,
344 ) -> c_int;
345 pub fn nfc_initiator_transceive_bits(
346 pnd: *mut nfc_device,
347 pbtTx: *const u8,
348 szTxBits: size_t,
349 pbtTxPar: *const u8,
350 pbtRx: *mut u8,
351 szRx: size_t,
352 pbtRxPar: *mut u8,
353 ) -> c_int;
354 pub fn nfc_initiator_transceive_bytes_timed(
355 pnd: *mut nfc_device,
356 pbtTx: *const u8,
357 szTx: size_t,
358 pbtRx: *mut u8,
359 szRx: size_t,
360 cycles: *mut u32,
361 ) -> c_int;
362 pub fn nfc_initiator_transceive_bits_timed(
363 pnd: *mut nfc_device,
364 pbtTx: *const u8,
365 szTxBits: size_t,
366 pbtTxPar: *const u8,
367 pbtRx: *mut u8,
368 szRx: size_t,
369 pbtRxPar: *mut u8,
370 cycles: *mut u32,
371 ) -> c_int;
372 pub fn nfc_initiator_target_is_present(pnd: *mut nfc_device, pnt: *const nfc_target) -> c_int;
373
374 pub fn nfc_target_init(
375 pnd: *mut nfc_device,
376 pnt: *mut nfc_target,
377 pbtRx: *mut u8,
378 szRx: size_t,
379 timeout: c_int,
380 ) -> c_int;
381 pub fn nfc_target_send_bytes(
382 pnd: *mut nfc_device,
383 pbtTx: *const u8,
384 szTx: size_t,
385 timeout: c_int,
386 ) -> c_int;
387 pub fn nfc_target_receive_bytes(
388 pnd: *mut nfc_device,
389 pbtRx: *mut u8,
390 szRx: size_t,
391 timeout: c_int,
392 ) -> c_int;
393 pub fn nfc_target_send_bits(
394 pnd: *mut nfc_device,
395 pbtTx: *const u8,
396 szTxBits: size_t,
397 pbtTxPar: *const u8,
398 ) -> c_int;
399 pub fn nfc_target_receive_bits(
400 pnd: *mut nfc_device,
401 pbtRx: *mut u8,
402 szRx: size_t,
403 pbtRxPar: *mut u8,
404 ) -> c_int;
405
406 pub fn nfc_strerror(pnd: *const nfc_device) -> *const c_char;
407 pub fn nfc_strerror_r(pnd: *const nfc_device, buf: *mut c_char, buflen: size_t) -> c_int;
408 pub fn nfc_perror(pnd: *const nfc_device, s: *const c_char);
409 pub fn nfc_device_get_last_error(pnd: *const nfc_device) -> c_int;
410
411 pub fn nfc_device_get_name(pnd: *mut nfc_device) -> *const c_char;
412 pub fn nfc_device_get_connstring(pnd: *mut nfc_device) -> *const c_char;
413 pub fn nfc_device_get_supported_modulation(
414 pnd: *mut nfc_device,
415 mode: nfc_mode,
416 supported_mt: *mut *const nfc_modulation_type,
417 ) -> c_int;
418 pub fn nfc_device_get_supported_baud_rate(
419 pnd: *mut nfc_device,
420 nmt: nfc_modulation_type,
421 supported_br: *mut *const nfc_baud_rate,
422 ) -> c_int;
423 pub fn nfc_device_get_supported_baud_rate_target_mode(
424 pnd: *mut nfc_device,
425 nmt: nfc_modulation_type,
426 supported_br: *mut *const nfc_baud_rate,
427 ) -> c_int;
428
429 pub fn nfc_device_set_property_int(
430 pnd: *mut nfc_device,
431 property: nfc_property,
432 value: c_int,
433 ) -> c_int;
434 pub fn nfc_device_set_property_bool(
435 pnd: *mut nfc_device,
436 property: nfc_property,
437 bEnable: bool,
438 ) -> c_int;
439
440 pub fn iso14443a_crc(pbtData: *mut u8, szLen: size_t, pbtCrc: *mut u8);
441 pub fn iso14443a_crc_append(pbtData: *mut u8, szLen: size_t);
442 pub fn iso14443b_crc(pbtData: *mut u8, szLen: size_t, pbtCrc: *mut u8);
443 pub fn iso14443b_crc_append(pbtData: *mut u8, szLen: size_t);
444 pub fn iso14443a_locate_historical_bytes(
445 pbtAts: *mut u8,
446 szAts: size_t,
447 pszTk: *mut size_t,
448 ) -> *mut u8;
449
450 pub fn nfc_free(p: *mut c_void);
451 pub fn nfc_version() -> *const c_char;
452 pub fn nfc_device_get_information_about(pnd: *mut nfc_device, buf: *mut *mut c_char) -> c_int;
453
454 pub fn str_nfc_modulation_type(nmt: nfc_modulation_type) -> *const c_char;
455 pub fn str_nfc_baud_rate(nbr: nfc_baud_rate) -> *const c_char;
456 pub fn str_nfc_target(buf: *mut *mut c_char, pnt: *const nfc_target, verbose: bool) -> c_int;
457
458 pub fn nfc_emulate_target(
459 pnd: *mut nfc_device,
460 emulator: *mut nfc_emulator,
461 timeout: c_int,
462 ) -> c_int;
463}
464
465#[cfg(test)]
466mod tests {
467 use super::*;
468
469 #[test]
470 fn can_call_libnfc_version() {
471 let version = unsafe { nfc_version() };
472
473 assert!(!version.is_null());
474 }
475
476 #[test]
477 fn target_layout_matches_libnfc_1_8_on_64_bit() {
478 #[cfg(target_pointer_width = "64")]
479 {
480 assert_eq!(std::mem::size_of::<nfc_target_info>(), 283);
481 assert_eq!(std::mem::size_of::<nfc_modulation>(), 8);
482 assert_eq!(std::mem::size_of::<nfc_target>(), 291);
483 assert_eq!(std::mem::align_of::<nfc_target_info>(), 1);
484 assert_eq!(std::mem::align_of::<nfc_target>(), 1);
485 }
486 }
487}