bluetooth connection fail with bluetoothctl command

0

I tried bluetooth connection test in the Ubuntu under Vmware environment. Ubuntu is 14.04 lts, Bluetooth is USB-dongle and BT stack is Bluez 5.35. I don't use pulseaudio.

I used bluetoothctl command to scan, pairing and connection. But the connection is fail. Below is the log of bluetoothctl

$ sudo bluetoothctl
[bluetooth]# power on
[bluetooth]# show
Controller 00:1A:7D:DA:xx:xx (public)
Name: ubuntu
Alias: ubuntu-0
Class: 0x00000000
Powered: yes
Discoverable: no
Pairable: yes
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
Modalias: usb:v1D6Bp0246d0532
Discovering: no
[bluetooth]# scan on         // Wait until found BT headset
[bluetooth]# scan off
[bluetooth]# devices
Device 11:11:22:xx:xx:xx Test
Device 0C:E0:E4:xx:xx:xx PLT_Legend

[bluetooth]# pair 0C:E0:E4:xx:xx:xx    // try pairing with 0C:E0:E4:xx:xx:xx
Attempting to pair with 0C:E0:E4:xx:xx:xx
[CHG] Device 0C:E0:E4:xx:xx:xx Connected: yes
[PLT_Legend]# interfaces_added
[CHG] Device 0C:E0:E4:xx:xx:xx Modalias: bluetooth:v0055p0113d0067
[CHG] Device 0C:E0:E4:xx:xx:xx UUIDs: 00001108-0000-1000-8000-00805f9b34fb
[CHG] Device 0C:E0:E4:xx:xx:xx UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device 0C:E0:E4:xx:xx:xx UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device 0C:E0:E4:xx:xx:xx UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device 0C:E0:E4:xx:xx:xx UUIDs: 0000111e-0000-1000-8000-00805f9b34fb
[CHG] Device 0C:E0:E4:xx:xx:xx UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device 0C:E0:E4:xx:xx:xx UUIDs: 82972387-294e-4d62-97b5-2668aa35f618
[CHG] Device 0C:E0:E4:xx:xx:xx ServicesResolved: yes
[CHG] Device 0C:E0:E4:xx:xx:xx Paired: yes
Pairing successful
[CHG] Device 0C:E0:E4:xx:xx:xx ServicesResolved: no
[CHG] Device 0C:E0:E4:xx:xx:xx Connected: no
[PLT_Legend]# connect 0C:E0:E4:xx:xx:xx
Attempting to connect to 0C:E0:E4:xx:xx:xx
[CHG] Device 0C:E0:E4:xx:xx:xxConnected: yes
Failed to connect: org.bluez.Error.Failed

I found above bluez doesn't have a2dp profile. Actually, bluez5.x and pulseaudio is combined closely. If don't use pulseaudio, user has to add extra profile(a2dp, or hspag).

Below code is sample for add a2dpsink , a2dpsource and haspag.

#define A2DP_SOURCE_ENDPOINT "/MediaEndpoint/A2DPSource"
#define A2DP_SINK_ENDPOINT "/MediaEndpoint/A2DPSink"
#define HSP_AG_PROFILE "/Profile/HSPAGProfile"

#define PA_BLUETOOTH_UUID_HSP_AG      "00001112-0000-1000-8000-00805f9b34fb"
#define PA_BLUETOOTH_UUID_A2DP_SOURCE "0000110a-0000-1000-8000-00805f9b34fb"
#define PA_BLUETOOTH_UUID_A2DP_SINK   "0000110b-0000-1000-8000-00805f9b34fb"

static void register_profile_reply(DBusPendingCall *call, void *user_data)
{
    //struct bluetooth_profile *profile = user_data;
    DBusMessage *reply = dbus_pending_call_steal_reply(call);
    DBusError derr;

    dbus_error_init(&derr);
    if (!dbus_set_error_from_message(&derr, reply)) {
        printf("Profile %s registered", (char *)user_data);
        goto done;
    }

    //unregister_profile(profile);

    printf("bluetooth: RequestProfile error: %s, %s", derr.name,
                                derr.message);
    dbus_error_free(&derr);
done:
    dbus_message_unref(reply);
}
static DBusConnection *connection;
void btd_profile_add_hspag(const char *profile, const char *uuid) 
{
    DBusMessage *msg;
    DBusMessageIter iter, opt;
    DBusPendingCall *call;

    connection = btd_get_dbus_connection();
    msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
                        "org.bluez.ProfileManager1",
                        "RegisterProfile");
    if( msg == NULL ) {
        printf("%s : msg is null \n", __func__);
    }

    dbus_message_iter_init_append(msg, &iter);
    dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &profile);
    dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &uuid);
    dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
                    DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
                    DBUS_TYPE_STRING_AS_STRING
                    DBUS_TYPE_VARIANT_AS_STRING
                    DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
                    &opt);
    dbus_message_iter_close_container(&iter, &opt);
    if (!g_dbus_send_message_with_reply(connection, msg, &call, -1)) {
        printf("%s:%s - fail g_dbus_send_message_with_reply() \n", __FILE__, __func__);
        //unregister_profile(profile);
        goto failed;
    }
    dbus_pending_call_set_notify(call, register_profile_reply, &profile,
                                    NULL);
    dbus_pending_call_unref(call);
failed:
    dbus_message_unref(msg);
    return;
}
void btd_profile_add(void)
{
    btd_profile_add_hspag(HSP_AG_PROFILE, PA_BLUETOOTH_UUID_HSP_AG);
    btd_profile_add_hspag(A2DP_SOURCE_ENDPOINT, PA_BLUETOOTH_UUID_A2DP_SOURCE);
    btd_profile_add_hspag(A2DP_SINK_ENDPOINT, PA_BLUETOOTH_UUID_A2DP_SINK);
}

After that, the bluez has a2dp, hspag profile without pulseaudio. I can check it with "show" command of the bluetoothctl.

    [bluetooth]# show
    Controller 00:1A:7D:xx:xx:xx
    Name: ubuntu
    Alias: ubuntu-0
    Class: 0x000000
    Powered: yes
    Discoverable: no
    Pairable: yes
    UUID: Headset AG                (00001112-0000-1000-8000-00805f9b34fb)
    UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
    UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
    UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
    UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
    UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
    UUID: Audio Source              (0000110a-0000-1000-8000-00805f9b34fb)
    UUID: Audio Sink                (0000110b-0000-1000-8000-00805f9b34fb)
    Modalias: usb:v1D6Bp0246d0523
    Discovering: no

The bluetooth connection still fail even though a2dp profile is added. Through btmon trace, the rfcomm connection is disconnected, and next, l2cap connection is also disconnected. I don't know what i'm missing. What do i need other to run bluez 5.35 without pulseaudio?

linux
usb
adapter
bluez
l2cap
asked on Stack Overflow Jun 18, 2018 by shin2011 • edited Jun 25, 2018 by shin2011

1 Answer

0

Log shows that your "PLT_Legend" device supports A2DP SINK role, so your Ubuntu should act as A2DP SOURCE role. To make it work you need an working profile implementation.

You may not need complete implementation of A2DP source profile for sourcing the audio data, but at least you need to register basic functionality to make bluetoothd happy.

The below image is directly copied from here.

enter image description here

In the above sequence you can see that bluetoothd calls "SelectConfiguration" and "SetConfiguration" when a new device with A2DP capability is connected.

As you have observed, connection state is initially moved to connected and later fallback to "no". This is because, bluetoothd attempts to connect with the profiles (SDP service discovery protocol) after getting the low level connection. Once the low level connection is successful, the device is marked as connected and SDP proceeds.

During the SDP bluetoothd tries to get the capability of your device (ubuntu in this case) and negotiates with the end device (PLT_Legend) on the codecs support using "SelectConfiguration" and selects one using "SetConfiguration". Once this handshake is success, bluetoothd marks A2DP profile is connected.

So with your dummy registration of profiles, as it couldn't find the methods and proper codec returns, it marks the connection is failed and terminates the connection between Ubuntu and device.

If you don't want to use pulseaudio, you can try using bluez-alsa https://github.com/Arkq/bluez-alsa and start to listen on A2DP profiles. I think this package is already available in ubuntu repo, you can try

sudo apt-get install bluez-alsa

AFAIK, pulseaudio is not tightly bound with bluetooth, you can still implement your own A2DP imeplementation in way bluetoothd understands.

Note, bluez-alsa uses open source fdk-aac for AAC encoding and decoding.

answered on Stack Overflow Jun 22, 2018 by Parthiban

User contributions licensed under CC BY-SA 3.0