linux_gpib_rs/
asynchronous.rs1use crate::error::{GpibError, IbError};
2use crate::status::IbStatus;
3use std::os::raw::{c_int, c_void};
4
5pub async fn wait(ud: c_int, status_mask: IbStatus) -> Result<IbStatus, GpibError> {
6 let status_mask = status_mask.as_ibsta();
7 let status = IbStatus::from_ibsta(
8 tokio::task::spawn_blocking(move || unsafe { linux_gpib_sys::ibwait(ud, status_mask) })
9 .await?,
10 );
11 if status.err {
12 Err(GpibError::DriverError(status, IbError::current_error()?))
13 } else {
14 Ok(status)
15 }
16}
17
18pub async fn read(ud: c_int) -> Result<String, GpibError> {
19 const BUFFER_SIZE: usize = 1024;
20 let mut result: Vec<u8> = Vec::new();
21 loop {
22 let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
23 let status = IbStatus::from_ibsta(unsafe {
24 linux_gpib_sys::ibrda(
25 ud,
26 buffer.as_mut_ptr() as *mut c_void,
27 buffer.len().try_into()?,
28 )
29 });
30 if status.err {
31 return Err(GpibError::DriverError(status, IbError::current_error()?));
32 }
33 let status = wait(
34 ud,
35 IbStatus::default()
36 .with_timo(true)
37 .with_cmpl(true)
38 .with_end(true),
39 )
40 .await?;
41 if status.timo {
42 return Err(GpibError::Timeout);
43 }
44 let n_read: usize = unsafe { linux_gpib_sys::ibcntl }.try_into()?;
45 if n_read > 0 {
46 result.extend(buffer[0..n_read].to_vec());
47 }
48 if status.end || n_read < BUFFER_SIZE || n_read == 0 {
49 break;
50 }
51 }
52 let answer = String::from_utf8(result)?;
53 Ok(answer)
54}
55
56pub async fn write(ud: c_int, data: &str) -> Result<(), GpibError> {
57 let data = data.as_bytes();
58 let status = IbStatus::from_ibsta(unsafe {
59 linux_gpib_sys::ibwrta(ud, data.as_ptr() as *const c_void, data.len().try_into()?)
60 });
61 if status.err {
62 return Err(GpibError::DriverError(status, IbError::current_error()?));
63 }
64 let status = wait(
65 ud,
66 IbStatus::default()
67 .with_timo(true)
68 .with_cmpl(true)
69 .with_end(true)
70 .with_rqs(true),
71 )
72 .await?;
73 if status.timo {
74 Err(GpibError::Timeout)
75 } else if status.cmpl || status.end {
76 Ok(())
77 } else {
78 Err(GpibError::ValueError(format!(
79 "Unexpected status after waiting: {:?}",
80 status
81 )))
82 }
83}