|
| 1 | +use std::ffi::{CStr, CString}; |
| 2 | +use std::marker::PhantomData; |
| 3 | +use std::mem::{zeroed, MaybeUninit}; |
| 4 | +use std::ptr::{null, null_mut}; |
| 5 | +use std::str::FromStr; |
| 6 | + |
| 7 | +use anyhow::bail; |
| 8 | +use log::warn; |
| 9 | +use nfc1_sys::{ |
| 10 | + nfc_baud_rate_NBR_106, nfc_close, nfc_context, nfc_dep_mode_NDM_PASSIVE, nfc_device, nfc_device_get_name, nfc_exit, |
| 11 | + nfc_init, nfc_initiator_deselect_target, nfc_initiator_init, nfc_initiator_select_dep_target, nfc_open, nfc_target, |
| 12 | + nfc_version, |
| 13 | +}; |
| 14 | +use rnfc_traits::iso_dep::Reader as IsoDepReader; |
| 15 | + |
| 16 | +pub struct Context { |
| 17 | + context: *mut nfc_context, |
| 18 | +} |
| 19 | + |
| 20 | +impl Context { |
| 21 | + pub fn new() -> Self { |
| 22 | + let version = unsafe { CStr::from_ptr(nfc_version()) }.to_str().unwrap(); |
| 23 | + println!("libnfc v{}", version); |
| 24 | + |
| 25 | + let mut context: *mut nfc_context = null_mut(); |
| 26 | + unsafe { nfc_init(&mut context) }; |
| 27 | + |
| 28 | + Self { context } |
| 29 | + } |
| 30 | + |
| 31 | + pub fn open(&self, connstring: Option<&str>) -> Result<Device<'_>, anyhow::Error> { |
| 32 | + let connstring = connstring.map(|s| CString::new(s).unwrap()); |
| 33 | + let connstring_ptr = connstring.as_ref().map(|s| s.as_ptr()).unwrap_or(null()).cast_mut(); |
| 34 | + let device = unsafe { nfc_open(self.context, connstring_ptr) }; |
| 35 | + if device.is_null() { |
| 36 | + bail!("Error opening NFC reader"); |
| 37 | + } |
| 38 | + |
| 39 | + Ok(Device { |
| 40 | + context: self.context, |
| 41 | + device, |
| 42 | + _phantom: PhantomData, |
| 43 | + }) |
| 44 | + } |
| 45 | +} |
| 46 | + |
| 47 | +impl Drop for Context { |
| 48 | + fn drop(&mut self) { |
| 49 | + unsafe { nfc_exit(self.context) }; |
| 50 | + } |
| 51 | +} |
| 52 | + |
| 53 | +pub struct Device<'a> { |
| 54 | + context: *mut nfc_context, |
| 55 | + device: *mut nfc_device, |
| 56 | + _phantom: PhantomData<&'a ()>, |
| 57 | +} |
| 58 | + |
| 59 | +impl<'a> Device<'a> { |
| 60 | + pub fn name(&self) -> String { |
| 61 | + unsafe { CStr::from_ptr(nfc_device_get_name(self.device)) } |
| 62 | + .to_str() |
| 63 | + .unwrap() |
| 64 | + .to_string() |
| 65 | + } |
| 66 | + |
| 67 | + pub fn as_iso_dep(&mut self) -> Result<IsoDepTag<'_>, anyhow::Error> { |
| 68 | + let mut nt: nfc_target = unsafe { zeroed() }; |
| 69 | + |
| 70 | + let ret = unsafe { nfc_initiator_init(self.device) }; |
| 71 | + if ret < 0 { |
| 72 | + warn!("nfc_initiator_init failed") |
| 73 | + } |
| 74 | + |
| 75 | + let ret = unsafe { |
| 76 | + nfc_initiator_select_dep_target( |
| 77 | + self.device, |
| 78 | + nfc_dep_mode_NDM_PASSIVE, |
| 79 | + nfc_baud_rate_NBR_106, |
| 80 | + null(), |
| 81 | + &mut nt, |
| 82 | + 1000, |
| 83 | + ) |
| 84 | + }; |
| 85 | + if ret < 0 { |
| 86 | + warn!("nfc_initiator_select_dep_target failed") |
| 87 | + } |
| 88 | + |
| 89 | + Ok(IsoDepTag { |
| 90 | + device: self.device, |
| 91 | + _phantom: PhantomData, |
| 92 | + }) |
| 93 | + } |
| 94 | +} |
| 95 | + |
| 96 | +impl<'a> Drop for Device<'a> { |
| 97 | + fn drop(&mut self) { |
| 98 | + unsafe { nfc_close(self.device) }; |
| 99 | + } |
| 100 | +} |
| 101 | + |
| 102 | +pub struct IsoDepTag<'a> { |
| 103 | + device: *mut nfc_device, |
| 104 | + _phantom: PhantomData<&'a ()>, |
| 105 | +} |
| 106 | + |
| 107 | +impl<'a> Drop for IsoDepTag<'a> { |
| 108 | + fn drop(&mut self) { |
| 109 | + if (unsafe { nfc_initiator_deselect_target(self.device) } < 0) { |
| 110 | + warn!("nfc_initiator_deselect_target failed") |
| 111 | + } |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +impl<'a> IsoDepReader for IsoDepTag<'a> { |
| 116 | + type Error = anyhow::Error; |
| 117 | + |
| 118 | + async fn transceive(&mut self, tx: &[u8], rx: &mut [u8]) -> Result<usize, Self::Error> { |
| 119 | + todo!() |
| 120 | + } |
| 121 | +} |
| 122 | + |
| 123 | +/* |
| 124 | +
|
| 125 | +
|
| 126 | +
|
| 127 | + printf("Sending: %s\n", abtTx); |
| 128 | + int res; |
| 129 | + if ((res = nfc_initiator_transceive_bytes(pnd, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 0)) < 0) { |
| 130 | + nfc_perror(pnd, "nfc_initiator_transceive_bytes"); |
| 131 | + nfc_close(pnd); |
| 132 | + nfc_exit(context); |
| 133 | + exit(EXIT_FAILURE); |
| 134 | + } |
| 135 | +
|
| 136 | + abtRx[res] = 0; |
| 137 | + printf("Received: %s\n", abtRx); |
| 138 | +
|
| 139 | + if (nfc_initiator_deselect_target(pnd) < 0) { |
| 140 | + nfc_perror(pnd, "nfc_initiator_deselect_target"); |
| 141 | + nfc_close(pnd); |
| 142 | + nfc_exit(context); |
| 143 | + exit(EXIT_FAILURE); |
| 144 | + } |
| 145 | +
|
| 146 | +*/ |
0 commit comments