I'm trying to send data between a linux machine (Ubuntu 25.04, Bluetooth 5.3) and an Android phone.
l2cap socket gets successfully opened, works from Linux -> Android and Android -> Linux.
Reads from Linux go without any problems.
However, write_all(&buf) on OwnedWriteHalf is stuck on endlessly repeating Poll::Pending.
(guard is ready, but sock::send() errors (would block)).
After quite some time digging, found that output buffer of a channel is full on creation.
Which's I see by these prints added to fn accept()
println!("bytes in input buffer: {:?}", ioctl_read::<c_int>(&fd, libc::TIOCINQ));
println!("bytes in output buffer: {:?}", ioctl_read::<c_int>(&fd, libc::TIOCOUTQ));
// bytes in input buffer: Ok(0)
// bytes in output buffer: Ok(212992)
// ^^ it's size is the same
I've tried clearing output buf with no luck.
First tried to resize it to 0 then back to it's current size via this fn, as impl for Socket
/// Attempts to flush output buffer
pub fn flush_output_buffer(&self) -> std::io::Result<()> {
let socket = self.fd.get_ref();
// Get current output buffer size
let current_size: i32 = sock::getsockopt(socket, SOL_SOCKET, SO_SNDBUF)?;
// Set output buf to 0
sock::setsockopt(socket, SOL_SOCKET, SO_SNDBUF, &0)?;
// Set output buf to its original size, in hope that it's cleared in the process
sock::setsockopt(socket, SOL_SOCKET, SO_SNDBUF, ¤t_size)?;
Ok(())
}
After that the output buf is double the size it was before (ok, expected, libc docs say it *2 the passed val, whatever), but what's important - still fully filled.
Also tried TCFLSH in accept() fn
println!("On socket accept(), TCFLSH: {} ", unsafe {
libc::ioctl(fd.as_raw_fd(), libc::TCFLSH, libc::TCIOFLUSH)
});
println!("last err: {:?}", Error::last_os_error());
// On socket accept(), TCFLSH: -1
// last err: Os { code: 25, kind: Uncategorized, message: "Inappropriate ioctl for device" }
Soo.. no luck here either.
That's a strange behavior that socket fd gets filled in output buf.
I guess that's something screwed up in my OS, not in bluer and bluez.
Still, did anybody see something like that? Maybe it's not an uncommon issue..
And any possible workaround that comes to mind?
I'm trying to send data between a linux machine (Ubuntu 25.04, Bluetooth 5.3) and an Android phone.
l2cap socket gets successfully opened, works from Linux -> Android and Android -> Linux.
Reads from Linux go without any problems.
However, write_all(&buf) on OwnedWriteHalf is stuck on endlessly repeating Poll::Pending.
(guard is ready, but sock::send() errors (would block)).
After quite some time digging, found that output buffer of a channel is full on creation.
Which's I see by these prints added to fn accept()
I've tried clearing output buf with no luck.
First tried to resize it to 0 then back to it's current size via this fn, as impl for Socket
After that the output buf is double the size it was before (ok, expected, libc docs say it *2 the passed val, whatever), but what's important - still fully filled.
Also tried TCFLSH in accept() fn
Soo.. no luck here either.
That's a strange behavior that socket fd gets filled in output buf.
I guess that's something screwed up in my OS, not in bluer and bluez.
Still, did anybody see something like that? Maybe it's not an uncommon issue..
And any possible workaround that comes to mind?