Skip to content

Commit cfd7fbd

Browse files
committed
libnfc: wip
1 parent 1f04e99 commit cfd7fbd

File tree

3 files changed

+166
-0
lines changed

3 files changed

+166
-0
lines changed

rnfc-libnfc/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "rnfc-libnfc"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
anyhow = "1.0.98"
8+
hex-literal = "0.4.1"
9+
log = "0.4.20"
10+
nfc1-sys = { version = "0.3.9", default-features = false, features = [] }
11+
rnfc-traits = { path = "../rnfc-traits" }

rnfc-libnfc/examples/basic.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use rnfc_libnfc::Context;
2+
3+
fn main() {
4+
let ctx = Context::new();
5+
let mut dev = ctx.open(None).unwrap();
6+
println!("name: {}", dev.name());
7+
8+
let _dep = dev.as_iso_dep().unwrap();
9+
}

rnfc-libnfc/src/lib.rs

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
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

Comments
 (0)