Skip to content

Commit b1effce

Browse files
committed
l2cap: add non-blocking read and write APIs.
1 parent 020bf83 commit b1effce

File tree

5 files changed

+74
-3
lines changed

5 files changed

+74
-3
lines changed

src/android/l2cap_channel.rs

+30-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::sync::Arc;
22
use std::{fmt, slice, thread};
33

4-
use async_channel::{Receiver, Sender};
4+
use async_channel::{Receiver, Sender, TryRecvError, TrySendError};
55
use java_spaghetti::{ByteArray, Global, Local, PrimitiveArray};
66
use tracing::{debug, warn};
77

@@ -151,7 +151,27 @@ impl L2capChannelReader {
151151
.stream
152152
.recv()
153153
.await
154-
.map_err(|_| Error::new(ErrorKind::ConnectionFailed, None, "L2CAP channel is closed".to_string()))?;
154+
.map_err(|_| Error::new(ErrorKind::ConnectionFailed, None, "channel is closed".to_string()))?;
155+
156+
if packet.len() > buf.len() {
157+
return Err(Error::new(
158+
ErrorKind::InvalidParameter,
159+
None,
160+
"Buffer is too small".to_string(),
161+
));
162+
}
163+
164+
buf[..packet.len()].copy_from_slice(&packet);
165+
166+
Ok(packet.len())
167+
}
168+
169+
#[inline]
170+
pub fn try_read(&mut self, buf: &mut [u8]) -> Result<usize> {
171+
let packet = self.stream.try_recv().map_err(|e| match e {
172+
TryRecvError::Empty => Error::new(ErrorKind::NotReady, None, "no received packet in queue".to_string()),
173+
TryRecvError::Closed => Error::new(ErrorKind::ConnectionFailed, None, "channel is closed".to_string()),
174+
})?;
155175

156176
if packet.len() > buf.len() {
157177
return Err(Error::new(
@@ -188,7 +208,14 @@ impl L2capChannelWriter {
188208
self.stream
189209
.send(packet.to_vec())
190210
.await
191-
.map_err(|_| Error::new(ErrorKind::ConnectionFailed, None, "L2CAP channel is closed".to_string()))
211+
.map_err(|_| Error::new(ErrorKind::ConnectionFailed, None, "channel is closed".to_string()))
212+
}
213+
214+
pub fn try_write(&mut self, packet: &[u8]) -> Result<()> {
215+
self.stream.try_send(packet.to_vec()).map_err(|e| match e {
216+
TrySendError::Closed(_) => Error::new(ErrorKind::ConnectionFailed, None, "channel is closed".to_string()),
217+
TrySendError::Full(_) => Error::new(ErrorKind::NotReady, None, "No buffer space for write".to_string()),
218+
})
192219
}
193220

194221
pub async fn close(&mut self) -> Result<()> {

src/bluer/l2cap_channel.rs

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ impl L2capChannelReader {
1212
todo!()
1313
}
1414

15+
pub fn try_read(&mut self, _buf: &mut [u8]) -> Result<usize> {
16+
todo!()
17+
}
18+
1519
pub async fn close(&mut self) -> Result<()> {
1620
todo!()
1721
}
@@ -32,6 +36,10 @@ impl L2capChannelWriter {
3236
todo!()
3337
}
3438

39+
pub fn try_write(&mut self, _packet: &[u8]) -> Result<()> {
40+
todo!()
41+
}
42+
3543
pub async fn close(&mut self) -> Result<()> {
3644
todo!()
3745
}

src/corebluetooth/l2cap_channel.rs

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ impl L2capChannelReader {
1212
todo!()
1313
}
1414

15+
pub fn try_read(&mut self, _buf: &mut [u8]) -> Result<usize> {
16+
todo!()
17+
}
18+
1519
pub async fn close(&mut self) -> Result<()> {
1620
todo!()
1721
}
@@ -32,6 +36,10 @@ impl L2capChannelWriter {
3236
todo!()
3337
}
3438

39+
pub fn try_write(&mut self, _packet: &[u8]) -> Result<()> {
40+
todo!()
41+
}
42+
3543
pub async fn close(&mut self) -> Result<()> {
3644
todo!()
3745
}

src/l2cap_channel.rs

+20
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ impl L2capChannelReader {
6262
self.reader.read(buf).await
6363
}
6464

65+
/// Try reading a packet from the L2CAP channel.
66+
///
67+
/// The packet is written to the start of `buf`, and the packet length is returned.
68+
///
69+
/// If no packet is immediately available for reading, this returns an error with kind `NotReady`.
70+
#[inline]
71+
pub fn try_read(&mut self, buf: &mut [u8]) -> Result<usize> {
72+
self.reader.try_read(buf)
73+
}
74+
6575
/// Close the L2CAP channel.
6676
///
6777
/// This closes the entire channel, not just the read half.
@@ -76,11 +86,21 @@ impl L2capChannelReader {
7686

7787
impl L2capChannelWriter {
7888
/// Write a packet to the L2CAP channel.
89+
///
90+
/// If the buffer is full, this will wait until there's buffer space for the packet.
7991
#[inline]
8092
pub async fn write(&mut self, packet: &[u8]) -> Result<()> {
8193
self.writer.write(packet).await
8294
}
8395

96+
/// Try writing a packet to the L2CAP channel.
97+
///
98+
/// If there's no buffer space, this returns an error with kind `NotReady`.
99+
#[inline]
100+
pub fn try_write(&mut self, packet: &[u8]) -> Result<()> {
101+
self.writer.try_write(packet)
102+
}
103+
84104
/// Close the L2CAP channel.
85105
///
86106
/// This closes the entire channel, not just the write half.

src/windows/l2cap_channel.rs

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ impl L2capChannelReader {
1212
todo!()
1313
}
1414

15+
pub fn try_read(&mut self, _buf: &mut [u8]) -> Result<usize> {
16+
todo!()
17+
}
18+
1519
pub async fn close(&mut self) -> Result<()> {
1620
todo!()
1721
}
@@ -32,6 +36,10 @@ impl L2capChannelWriter {
3236
todo!()
3337
}
3438

39+
pub fn try_write(&mut self, _packet: &[u8]) -> Result<()> {
40+
todo!()
41+
}
42+
3543
pub async fn close(&mut self) -> Result<()> {
3644
todo!()
3745
}

0 commit comments

Comments
 (0)