Базовый клиент BLE с D-Bus BlueZ

Я работаю с (всем любимым) BlueZ 5.40, скомпилированным и работающим с экспериментальными функциями, и мне нужно отсканировать устройства LE, выполнить сопряжение и подключиться к одному, а также прочитать / записать характеристику через D-Bus API. Я изучил источники hcitool, gatttool и bluetootctl и сделал базовое приложение, используя GDBus. Однако есть несколько проблем с этим.

  1. Сканирование не добавляет / org / bluez / hci0 / dev_XX_XX_XX_XX_XX_XX obj. путь к автобусу org.bluez (проверяется с помощью d-футов). Это не удивительно, учитывая, что он не основан на D-Bus, но я, когда использую StartDiscovery, он вообще не обнаруживает мое устройство. Ни один не делает bluetoothctl.

После этого я использовал gatttool и simple-agent в качестве обходного пути для создания пути к объекту, а затем подключился с помощью моей программы, но столкнулся с другой проблемой:

  1. Когда я пытаюсь прочитать характеристику, я получаю ошибку «Соединение закрыто (18)». Я подозреваю, что это не имеет никакого отношения к соединению между устройствами Bluetooth и говорит о самой D-Bus, потому что, когда я пытаюсь установить фильтр сканирования только для устройств LE, используя SetDiscoveryFilter, я получаю ту же ошибку.

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

  1. Как сканировать устройства LE с помощью GDBus? Если это невозможно, как добавить устройство вручную или убедить bluetoothd сделать это для меня?

  2. Как правильно читать характеристику?

Код довольно длинный даже после сокращения, поэтому я поместил его на pastebin:
http://pastebin.com/YNLMF0qC.
Компилировать с g++ -std=c++11 $(pkg-config --cflags glib-2.0 gobject-2.0 gio-2.0) ./main.cpp $(pkg-config --libs glib-2.0 gobject-2.0 gio-2.0 bluez)

2

Решение

Наконец-то все правильно поняли.
1. Недавно была решена с помощью BlueZ 5.41. Мое устройство было «сканируемым», но не «обнаруживаемым». Это означало, что он транслировал рекламные пакеты, но потому что он не разрешал соединение без PIN-кода для обнаружения дополнительных услуг. В BlueZ 5.41, если вы устанавливаете какой-либо фильтр с помощью SetDiscoveryFilter, эти устройства также становятся видимыми во время сканирования. Это недавнее (и вовсе не интуитивно понятное) дополнение к https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/adapter-api.txt:

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

  1. Была чисто моя ошибка. Как я уже сказал, я получил ту же ошибку на ReadValue и SetDiscoveryFilter, но эта ошибка не имеет ничего общего с подключением DBus. Это было вызвано неверным аргументом GVariant. Правильная форма "(a{sv})" не «({sv})». Например GVariant *args = g_variant_new_parsed("({'Transport': <%s>},)", "le"); для SetDiscoveryFilter и GVariant *args = g_variant_new_parsed("({'offset': <%q>},)", offset); работает отлично.
2

Другие решения

Вы не должны использовать функции Bluez C вообще. Вместо этого используйте более новые функции GDBus. В https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/adapter-api.txt Вы можете узнать, как сканировать. Вызови StartDiscovery. Устройства DBus будут добавлены по мере их обнаружения. Прослушайте добавленный интерфейсом сигнал для обнаружения новых устройств. Странно, что вы говорите, что устройства не обнаружены, так как оно должно работать.

Метод ReadValue должен работать. Вы подключены к устройству во время чтения?

Также проверьте с помощью hciconfig, что слой hci — UP. Если ничего не работает, вы всегда можете запустить «sudo btmon», чтобы получить представление о том, что происходит.

1

По вопросам рекламы [email protected]