蓝牙连接失败,使用bluetoothctl命令

时间:2018-06-18 08:38:24

标签: linux usb adapter bluez l2cap

我在Vmware环境下的Ubuntu中尝试过蓝牙连接测试。 Ubuntu是14.04 lts,蓝牙是USB加密狗,BT堆栈是Bluez 5.35。 我没有使用pulseaudio。

我使用bluetoothctl命令扫描,配对和连接。 但是连接失败了。以下是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

我发现上面的bluez没有a2dp配置文件。 实际上,bluez5.x和pulseaudio紧密结合在一起。如果不使用pulseaudio,用户必须添加额外的配置文件(a2dp或hspag)。

下面的代码是添加a2dpsink,a2dpsource和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);
}

之后,bluez有一个没有pulseaudio的a2dp,hspag配置文件。 我可以用" show"来检查它。 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

即使添加了a2dp配置文件,蓝牙连接仍会失败。 通过btmon跟踪,rfcomm连接断开连接,接下来,l2cap连接也断开连接。 我不知道自己错过了什么。 如果没有pulseaudio,我还需要运行bluez 5.35吗?

1 个答案:

答案 0 :(得分:0)

日志显示您的“ PLT_Legend”设备支持A2DP SINK角色,因此您的Ubuntu应该充当A2DP SOURCE角色。要使其正常工作,您需要一个有效的配置文件实施。

您可能不需要完全实施A2DP源配置文件来获取音频数据,但是至少您需要注册基本功能才能使蓝牙开心。

下面的图像直接从here复制。

enter image description here

在上述顺序中,您可以看到在连接具有A2DP功能的新设备时,蓝牙呼叫“ SelectConfiguration ”和“ SetConfiguration ”。

如您所见,连接状态最初移至已连接,然后回退至“否”。这是因为,蓝牙在获得低级连接后会尝试与配置文件(SDP服务发现协议)进行连接。低级连接成功后,该设备将标记为已连接,并且SDP继续。

在SDP期间,蓝牙会尝试获取设备的功能(在这种情况下为ubuntu),并使用“ SelectConfiguration”与编解码器支持上的终端设备(PLT_Legend)进行协商,并使用“ SetConfiguration”选择一个。一旦握手成功,便会连接蓝牙标记A2DP配置文件。

因此,使用配置文件的虚拟注册时,由于找不到方法并返回了正确的编解码器,因此它指示连接失败并终止了Ubuntu与设备之间的连接。

如果您不想使用Pulseaudio,可以尝试使用bluez-alsa https://github.com/Arkq/bluez-alsa并开始收听A2DP配置文件。我认为该软件包已在ubuntu repo中提供,您可以尝试

sudo apt-get install bluez-alsa

AFAIK,pulseaudio并没有与蓝牙紧密结合,您仍然可以按照蓝牙理解的方式实施自己的A2DP实现。

请注意,bluez-alsa使用开源fdk-aac进行AAC编码和解码。