Сбой подключения Bluetooth с помощью команды bluetoothctl

Я попытался проверить соединение Bluetooth в Ubuntu в среде Vmware. Ubuntu - 14,04 лтс, Bluetooth - 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 имеет профиль a2dp, hspag без pulseaudio. Я могу проверить это с помощью команды "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

Соединение Bluetooth по-прежнему не удается, даже если добавлен профиль a2dp. Через трассировку btmon соединение rfcomm отключается, а затем соединение l2cap также отключается. Я не знаю, что мне не хватает. Что мне нужно для запуска bluez 5.35 без pulseaudio?

1 ответ

Журнал показывает, что ваше устройство "PLT_Legend" поддерживает роль A2DP SINK, поэтому ваша Ubuntu должна выступать в роли роли A2DP SOURCE. Чтобы это работало, вам нужна реализация рабочего профиля.

Вам может не потребоваться полная реализация исходного профиля A2DP для получения аудиоданных, но, по крайней мере, вам нужно зарегистрировать базовые функции, чтобы сделать Bluetooth счастливым.

Изображение ниже скопировано прямо отсюда.

В приведенной выше последовательности вы видите, что bluetoothd вызывает "SelectConfiguration" и "SetConfiguration", когда подключено новое устройство с возможностью A2DP.

Как вы уже заметили, состояние соединения первоначально перемещается в состояние "подключено", а затем возвращается к "нет". Это связано с тем, что bluetoothd пытается соединиться с профилями (протокол обнаружения службы SDP) после получения низкоуровневого соединения. Как только низкоуровневое соединение выполнено успешно, устройство помечается как подключенное, и SDP продолжается.

Во время SDP bluetoothd пытается получить возможности вашего устройства (в данном случае ubuntu) и согласовывает с конечным устройством (PLT_Legend) поддержку кодеков с помощью "SelectConfiguration" и выбирает один с помощью "SetConfiguration". Как только это рукопожатие прошло успешно, bluetoothd отмечает профиль A2DP.

Таким образом, с вашей фиктивной регистрацией профилей, поскольку он не может найти методы и правильные возвраты кодека, он отмечает, что соединение не установлено, и разрывает соединение между Ubuntu и устройством.

Если вы не хотите использовать pulseaudio, вы можете попробовать использовать bluez-alsa https://github.com/Arkq/bluez-alsa и начать слушать профили A2DP. Я думаю, что этот пакет уже доступен в репозитории Ubuntu, вы можете попробовать

sudo apt-get install bluez-alsa

AFAIK, pulseaudio не тесно связан с Bluetooth, вы все равно можете реализовать свое собственное внедрение A2DP так, как BluetoothD понимает.

Обратите внимание, что bluez-alsa использует открытый код fdk-aac для кодирования и декодирования AAC.

Другие вопросы по тегам