Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L2CAP connection fails if there's no delay after connect #163

Open
lmore377 opened this issue Jan 24, 2025 · 1 comment
Open

L2CAP connection fails if there's no delay after connect #163

lmore377 opened this issue Jan 24, 2025 · 1 comment
Assignees

Comments

@lmore377
Copy link

lmore377 commented Jan 24, 2025

I'm trying to connect to the L2CAP channel for AVRCP/OBEX image transfer on an iOS device. I was having an issue where I would get the error { kind: Internal(Io(NotConnected)), message: "Transport endpoint is not connected (os error 107)" } when trying to send data unless I ran my code repeatedly, and even then it would only work about 10% of the time. Eventually I figured out that if I add a sleep/delay after the connect function, my code would start working fine. Am I doing something wrong or is there a bug?

Here's my Rust code:

use bluer::l2cap::{Opts, Socket, SocketAddr};
use bluer::AddressType;
use tokio::io::AsyncWriteExt;
use std::{thread, time::Duration};

const OBEX_HELLO: [u8; 26] = [
    0x80, 0x00, 0x1a, 0x15, 0x00, 0x06, 0x9b, 0x46, 0x00, 0x13, 0x71, 0x63, 0xdd, 0x54, 0x4a, 0x7e,
    0x11, 0xe2, 0xb4, 0x7c, 0x00, 0x50, 0xc2, 0x49, 0x00, 0x48,
];

fn create_l2cap_opts() -> Opts {
    let mut opts = Opts::default();
    opts.omtu = 672;
    opts.imtu = 1024;
    opts.flush_to = 65535;
    opts.mode = 3;
    opts.fcs = 1;
    opts.max_tx = 16;
    opts.txwin_size = 63;

    opts
}

#[tokio::main]
async fn main() -> bluer::Result<()> {
    let session = bluer::Session::new().await?;
    let adapter = session.adapter("hci0")?;
    adapter.set_powered(true).await?;
    let target_sa = SocketAddr::new(
        "B8:B2:F8:XX:XX:XX".parse().unwrap(), // MAC Obfuscated
        AddressType::BrEdr,
        0x1007,
    );

    println!("Connecting to {:?}", &target_sa);
    let socket = Socket::new_stream()?;
    socket.set_l2cap_opts(&create_l2cap_opts())?;

    println!("Before connection: {:?}", socket.l2cap_opts()?);
    let mut stream = socket.connect(target_sa).await.expect("connection failed");
    thread::sleep(Duration::from_millis(1500)); // If this is removed, connection fails most of the time
    println!("After connection: {:?}", stream.as_ref().l2cap_opts()?);

    stream.write_all(&OBEX_HELLO).await?;
    println!("Sent successfully");

    Ok(())
}

And some Python/PyBlueZ code with the same functionality for reference. In this code, I don't need the delay:

Python code
import bluetooth

bt_addr = "B8:B2:F8:XX:XX:XX" # MAC Obfuscated
psm = 0x1007
obexConnReq = bytes.fromhex("80001a1500069b4600137163dd544a7e11e2b47c0050c2490048")

sock = bluetooth.BluetoothSocket(bluetooth.L2CAP)
sock.set_l2cap_options([672, 1024, 65535, 3, 1, 16, 63])

print(f"Before connection: {sock.get_l2cap_options()}")

print(f"Connecting to {bt_addr} on PSM {psm}")
sock.connect((bt_addr, psm))
print(f"Connected to {bt_addr} on PSM {psm}.")

print(f"After connection: {sock.get_l2cap_options()}")

sock.send(obexConnReq)

print("Sent successfully")
@surban surban self-assigned this Jan 24, 2025
@surban
Copy link
Collaborator

surban commented Jan 24, 2025

@Neme Have you observed similar behavior?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants