Я работаю с (всем любимым) BlueZ 5.40, скомпилированным и работающим с экспериментальными функциями, и мне нужно отсканировать устройства LE, выполнить сопряжение и подключиться к одному, а также прочитать / записать характеристику через D-Bus API. Я изучил источники hcitool, gatttool и bluetootctl и сделал базовое приложение, используя GDBus. Однако есть несколько проблем с этим.
После этого я использовал gatttool и simple-agent в качестве обходного пути для создания пути к объекту, а затем подключился с помощью моей программы, но столкнулся с другой проблемой:
Всякий раз, когда я использую только функции Connect и Disconnect, кажется, что все работает нормально, но использование таких приложений ограничено.
Итак, мои вопросы:
Как сканировать устройства LE с помощью GDBus? Если это невозможно, как добавить устройство вручную или убедить bluetoothd сделать это для меня?
Как правильно читать характеристику?
Код довольно длинный даже после сокращения, поэтому я поместил его на 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)
Наконец-то все правильно поняли.
1. Недавно была решена с помощью BlueZ 5.41. Мое устройство было «сканируемым», но не «обнаруживаемым». Это означало, что он транслировал рекламные пакеты, но потому что он не разрешал соединение без PIN-кода для обнаружения дополнительных услуг. В BlueZ 5.41, если вы устанавливаете какой-либо фильтр с помощью SetDiscoveryFilter, эти устройства также становятся видимыми во время сканирования. Это недавнее (и вовсе не интуитивно понятное) дополнение к https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/adapter-api.txt:
Когда фильтр обнаружения установлен, объекты устройства будут созданы как новые
устройства с соответствующими критериями обнаруживаются независимо от того, являются ли они
подключаемый или обнаруживаемый, что позволяет прослушивать не подключаемые
и не обнаруживаемые устройства.
"(a{sv})"
не «({sv})». Например GVariant *args = g_variant_new_parsed("({'Transport': <%s>},)", "le");
для SetDiscoveryFilter и GVariant *args = g_variant_new_parsed("({'offset': <%q>},)", offset);
работает отлично. Вы не должны использовать функции Bluez C вообще. Вместо этого используйте более новые функции GDBus. В https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/adapter-api.txt Вы можете узнать, как сканировать. Вызови StartDiscovery. Устройства DBus будут добавлены по мере их обнаружения. Прослушайте добавленный интерфейсом сигнал для обнаружения новых устройств. Странно, что вы говорите, что устройства не обнаружены, так как оно должно работать.
Метод ReadValue должен работать. Вы подключены к устройству во время чтения?
Также проверьте с помощью hciconfig, что слой hci — UP. Если ничего не работает, вы всегда можете запустить «sudo btmon», чтобы получить представление о том, что происходит.