Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf93c85a

Browse files
authored
Merge pull request#41 from jreppnow/async-io-support
add basic support for async-io
2 parents5e100c5 +0eac426 commitf93c85a

File tree

5 files changed

+155
-2
lines changed

5 files changed

+155
-2
lines changed

‎Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ async-tokio = [ "tokio", "mio", "futures" ]
3131
netlink_tests = ["netlink"]
3232
vcan_tests = ["netlink"]
3333
utils = ["clap","anyhow"]
34+
async-io = ["dep:async-io" ]
3435

3536
[dependencies]
3637
embedded-can ="0.4"
@@ -48,16 +49,19 @@ neli = { version = "0.6", optional = true }
4849
tokio = {version ="1",features = ["net"],optional =true }
4950
mio = {version ="0.8",features = ["os-ext"],optional =true }
5051
futures = {version ="0.3",optional =true }
51-
52+
async-io = {version ="1.13",optional =true }
53+
5254
[dev-dependencies]
5355
anyhow ="1.0"
5456
ctrlc ="3.2.2"
5557
clap = {version ="4.0",features = ["derive"] }
5658
nb ="1.0"
57-
serial_test ="0.9"
5859
# TODO: Is it possible to only include these for async builds?
5960
futures-timer ="0.3"
6061
futures-util ="0.3"
62+
serial_test = {version ="2.0",features = ["async"]}
63+
async-std = {version ="1.12",features = ["attributes"]}
64+
futures ="0.3"
6165

6266
[dev-dependencies.tokio]
6367
version ="1"

‎src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ pub mod dump;
105105
pubmod socket;
106106
pubuse socket::{CanFdSocket,CanFilter,CanSocket,ShouldRetry,Socket};
107107

108+
#[cfg(feature ="async-io")]
109+
/// Bindings to use with async-io based async runtimes, like async-std and smol.
110+
pubmod async_io{
111+
pubusecrate::socket::async_io::{CanFdSocket,CanSocket};
112+
}
113+
108114
#[cfg(feature ="netlink")]
109115
mod nl;
110116

‎src/socket.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ pub use libc::{
3737
SOL_CAN_RAW,
3838
};
3939

40+
#[cfg(feature ="async-io")]
41+
pub(crate)mod async_io;
42+
4043
/// Check an error return value for timeouts.
4144
///
4245
/// Due to the fact that timeouts are reported as errors, calling `read_frame`

‎src/socket/async_io.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// socketcan/src/socket/async_io.rs
2+
//
3+
// Implements sockets for CANbus 2.0 and FD for SocketCAN on Linux.
4+
//
5+
// This file is part of the Rust 'socketcan-rs' library.
6+
//
7+
// Licensed under the MIT license:
8+
// <LICENSE or http://opensource.org/licenses/MIT>
9+
// This file may not be copied, modified, or distributed except according
10+
// to those terms.
11+
12+
//! Bindings to async-io for CANbus 2.0 and FD sockets using SocketCAN on Linux.
13+
14+
use std::io;
15+
16+
use async_io::Async;
17+
18+
usecrate::{frame::AsPtr,CanAnyFrame,CanFrame,Socket};
19+
20+
macro_rules! create_async_socket{
21+
($target_type:ident, $wrapped_type:ty, $frame_type:ty) =>{
22+
#[doc = concat!("Async version of ", stringify!($wrapped_type),". See the original type's documentation for details.")]
23+
#[allow(missing_copy_implementations)]
24+
#[derive(Debug)]
25+
pubstruct $target_type{
26+
inner:Async<$wrapped_type>,
27+
}
28+
29+
implTryFrom<$wrapped_type>for $target_type{
30+
typeError = io::Error;
31+
32+
fn try_from(value: $wrapped_type) ->Result<Self,Self::Error>{
33+
Ok(Self{
34+
inner:Async::new(value)?,
35+
})
36+
}
37+
}
38+
39+
impl $target_type{
40+
/// Open a named CAN device.
41+
///
42+
/// Usually the more common case, opens a socket can device by name, such
43+
/// as "can0", "vcan0", or "socan0".
44+
pubfn open(ifname:&str) -> io::Result<Self>{
45+
<$wrapped_type>::open(ifname)?.try_into()
46+
}
47+
48+
/// Permits access to the inner synchronous socket, for example to change options.
49+
pubfn blocking(&self) ->&$wrapped_type{
50+
self.inner.as_ref()
51+
}
52+
53+
/// Permits mutable access to the inner synchronous socket, for example to change options.
54+
pubfn blocking_mut(&mutself) ->&mut $wrapped_type{
55+
self.inner.as_mut()
56+
}
57+
58+
/// Writes a frame to the socket asynchronously.
59+
pubasyncfn write_frame<F>(&self, frame:&F) -> io::Result<()>
60+
where
61+
F:Into<$frame_type> +AsPtr,
62+
{
63+
self.inner.write_with(|fd| fd.write_frame(frame)).await
64+
}
65+
66+
/// Reads a frame from the socket asynchronously.
67+
pubasyncfn read_frame(&self) -> io::Result<$frame_type>{
68+
self.inner.read_with(|fd| fd.read_frame()).await
69+
}
70+
}
71+
};
72+
}
73+
74+
create_async_socket!(CanSocket,super::CanSocket,CanFrame);
75+
create_async_socket!(CanFdSocket,super::CanFdSocket,CanAnyFrame);

‎tests/cansocket-asyncio.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// socketcan/tests/cansocket.rs
2+
//
3+
// Integration tests for CAN sockets.
4+
//
5+
// This file is part of the Rust 'socketcan-rs' library.
6+
//
7+
// Licensed under the MIT license:
8+
// <LICENSE or http://opensource.org/licenses/MIT>
9+
// This file may not be copied, modified, or distributed except according
10+
// to those terms.
11+
12+
#[cfg(all(feature ="vcan_tests", feature ="async-io"))]
13+
use serial_test::serial;
14+
15+
#[cfg(all(feature ="vcan_tests", feature ="async-io"))]
16+
use socketcan::{
17+
async_io::CanFdSocketasAsyncCanFdSocket, async_io::CanSocketasAsyncCanSocket,
18+
frame::FdFlags,CanAnyFrame,CanFdFrame,EmbeddedFrame,Id,StandardId,
19+
};
20+
21+
// The virtual CAN interface to use for tests.
22+
#[cfg(all(feature ="vcan_tests", feature ="async-io"))]
23+
constVCAN:&str ="vcan0";
24+
25+
#[cfg(all(feature ="vcan_tests", feature ="async-io"))]
26+
#[serial]
27+
#[async_std::test]
28+
asyncfnasync_can_simple(){
29+
let writer =AsyncCanSocket::open(VCAN).unwrap();
30+
let reader =AsyncCanSocket::open(VCAN).unwrap();
31+
32+
let frame =
33+
socketcan::CanFrame::new(Id::from(StandardId::new(0x14).unwrap()),&[1,3,3,7]).unwrap();
34+
35+
let(write_result, read_result) =
36+
futures::join!(writer.write_frame(&frame), reader.read_frame());
37+
38+
assert!(write_result.is_ok());
39+
assert_eq!(frame.data(), read_result.unwrap().data());
40+
}
41+
42+
#[cfg(all(feature ="vcan_tests", feature ="async-io"))]
43+
#[serial]
44+
#[async_std::test]
45+
asyncfnasync_canfd_simple(){
46+
let writer =AsyncCanFdSocket::open(VCAN).unwrap();
47+
let reader =AsyncCanFdSocket::open(VCAN).unwrap();
48+
49+
let frame =CanFdFrame::with_flags(
50+
StandardId::new(111).unwrap(),
51+
// Note: OS may report this frame as a normal CAN frame if it is 8 or less bytes of payload..
52+
&[1,3,3,7,1,2,3,4,5],
53+
FdFlags::empty(),
54+
)
55+
.unwrap();
56+
57+
let(write_result, read_result) =
58+
futures::join!(writer.write_frame(&frame), reader.read_frame());
59+
60+
assert!(write_result.is_ok());
61+
match read_result.unwrap(){
62+
CanAnyFrame::Fd(read_frame) =>assert_eq!(read_frame.data(), frame.data()),
63+
_ =>panic!("Did not get FD frame back!"),
64+
}
65+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp