1#![allow(clippy::missing_safety_doc)]
10
11use crate::{Frame, Interface};
12
13#[repr(C)]
15pub struct CFrame {
16 channel: u8,
17 id: u32,
18 dlc: u8,
19 data: [u8; 64],
20 ext: u8,
23 fd: u8,
24 brs: u8,
25 esi: u8,
26 loopback: u8,
27 rtr: u8,
28 err: u8,
29}
30impl CFrame {
31 fn from_frame(f: Frame) -> CFrame {
32 CFrame {
33 channel: f.channel,
34 id: f.can_id,
35 dlc: f.can_dlc,
36 data: f.data_as_array(),
37 ext: if f.ext { 1 } else { 0 },
38 fd: if f.fd { 1 } else { 0 },
39 brs: if f.brs { 1 } else { 0 },
40 esi: if f.esi { 1 } else { 0 },
41 loopback: if f.loopback { 1 } else { 0 },
42 rtr: if f.rtr { 1 } else { 0 },
43 err: if f.err { 1 } else { 0 },
44 }
45 }
46}
47
48#[repr(C)]
52pub struct CInterface {
53 i: Option<Interface>,
54 c_rx_cb: Option<extern "C" fn(*const CFrame)>,
55}
56
57#[no_mangle]
63pub extern "C" fn cantact_init() -> *mut CInterface {
64 Box::into_raw(Box::new(CInterface {
65 i: None,
66 c_rx_cb: None,
67 }))
68}
69
70#[no_mangle]
73pub unsafe extern "C" fn cantact_deinit(ptr: *mut CInterface) -> i32 {
74 Box::from_raw(ptr);
75 0
76}
77
78#[no_mangle]
81pub unsafe extern "C" fn cantact_set_rx_callback(
82 ptr: *mut CInterface,
83 cb: Option<extern "C" fn(*const CFrame)>,
84) -> i32 {
85 let mut ci = &mut *ptr;
86 ci.c_rx_cb = cb;
87 0
88}
89
90#[no_mangle]
93pub unsafe extern "C" fn cantact_open(ptr: *mut CInterface) -> i32 {
94 let i = match Interface::new() {
95 Ok(i) => i,
96 Err(_) => return -1,
97 };
98 let ci = &mut *ptr;
99 ci.i = Some(i);
100 0
101}
102
103#[no_mangle]
106pub unsafe extern "C" fn cantact_close(ptr: *mut CInterface) -> i32 {
107 let mut ci = &mut *ptr;
108 ci.i = None;
109 0
110}
111
112#[no_mangle]
117pub unsafe extern "C" fn cantact_start(ptr: *mut CInterface) -> i32 {
118 let ci = &mut *ptr;
119
120 let cb = ci.c_rx_cb;
121 match &mut ci.i {
122 Some(i) => i
123 .start(move |f: Frame| {
124 match cb {
125 None => {}
126 Some(cb) => {
127 cb(&CFrame::from_frame(f));
128 }
129 };
130 })
131 .expect("failed to start device"),
132 None => return -1,
133 };
134 0
135}
136
137#[no_mangle]
139pub unsafe extern "C" fn cantact_stop(ptr: *mut CInterface) -> i32 {
140 let ci = &mut *ptr;
141 match &mut ci.i {
142 Some(i) => i.stop().expect("failed to stop device"),
143 None => return -1,
144 }
145 0
146}
147
148#[no_mangle]
150pub unsafe extern "C" fn cantact_transmit(ptr: *mut CInterface, cf: CFrame) -> i32 {
151 let ci = &mut *ptr;
152 let f = Frame {
153 channel: 0, can_id: cf.id,
155 can_dlc: cf.dlc,
156 data: cf.data.to_vec(),
157 ext: cf.ext > 0,
158 fd: cf.fd > 0,
159 brs: cf.brs > 0,
160 esi: cf.esi > 0,
161 loopback: false,
162 rtr: cf.rtr > 0,
163 err: cf.err > 0,
164 timestamp: None,
165 };
166 match &mut ci.i {
167 Some(i) => i.send(f).expect("failed to transmit frame"),
168 None => return -1,
169 };
170 0
171}
172
173#[no_mangle]
175pub unsafe extern "C" fn cantact_set_bitrate(
176 ptr: *mut CInterface,
177 channel: u8,
178 bitrate: u32,
179) -> i32 {
180 let ci = &mut *ptr;
181 match &mut ci.i {
182 Some(i) => i
183 .set_bitrate(channel as usize, bitrate)
184 .expect("failed to set bitrate"),
185 None => return -1,
186 }
187 0
188}
189
190#[no_mangle]
192pub unsafe extern "C" fn cantact_set_enabled(
193 ptr: *mut CInterface,
194 channel: u8,
195 enabled: u8,
196) -> i32 {
197 let ci = &mut *ptr;
198 match &mut ci.i {
199 Some(i) => i
200 .set_enabled(channel as usize, enabled > 0)
201 .expect("failed to enable channel"),
202 None => return -1,
203 }
204 0
205}
206
207#[no_mangle]
210pub unsafe extern "C" fn cantact_set_monitor(
211 ptr: *mut CInterface,
212 channel: u8,
213 enabled: u8,
214) -> i32 {
215 let ci = &mut *ptr;
216 match &mut ci.i {
217 Some(i) => i
218 .set_monitor(channel as usize, enabled > 0)
219 .expect("failed to set monitoring mode"),
220 None => return -1,
221 }
222 0
223}
224
225#[no_mangle]
228pub unsafe extern "C" fn cantact_set_hw_loopback(
229 ptr: *mut CInterface,
230 channel: u8,
231 enabled: u8,
232) -> i32 {
233 let ci = &mut *ptr;
234 match &mut ci.i {
235 Some(i) => i
236 .set_loopback(channel as usize, enabled > 0)
237 .expect("failed to enable channel"),
238 None => return -1,
239 }
240 0
241}
242
243#[no_mangle]
247pub unsafe extern "C" fn cantact_get_channel_count(ptr: *mut CInterface) -> i32 {
248 let ci = &mut *ptr;
249 match &mut ci.i {
250 Some(i) => i.channels() as i32,
251 None => -1,
252 }
253}