Skip to content

l2cap socket's output buffer is full on creation #174

@andrewzhurov

Description

@andrewzhurov

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, &current_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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions