Reputation: 552
I'm working with (everybody's favourite) BlueZ 5.40 compiled and run with experimental features and I need to scan for LE devices, pair and connect to one and read/write a characteristic via the D-Bus API. I have studied sources of hcitool, gatttool and bluetootctl and made a basic application using GDBus. However, there are several problems with it.
After that I used gatttool and simple-agent as a workaround to create the object path and then connect using my program but I encountered another problem:
Whenever I use only Connect and Disconnect functions everything seems to be working fine, but uses for applications like that are... limited. So my questions are:
How to scan for LE devices using GDBus? If that is not possible, how to add a device manually or persuade bluetoothd to do it for me?
How to read a characteristic properly?
The code is rather lengthy even after shortening, so I put it on pastebin:
http://pastebin.com/YNLMF0qC.
Compile with 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)
Upvotes: 3
Views: 5541
Reputation: 552
Finally got it right.
1. Was solved recently by BlueZ 5.41. My device was "scannable" but not "discoverable". Meaning it broadcasted advertising packets, but because it did not permit connection without PIN to discover further services. In BlueZ 5.41 if you set any filter using SetDiscoveryFilter these devices too become visible during scanning. This is a recent (and not intuitive at all!) addition to https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/adapter-api.txt:
When discovery filter is set, Device objects will be created as new devices with matching criteria are discovered regardless of they are connectable or discoverable which enables listening to non-connectable and non-discoverable devices.
"(a{sv})"
not "({sv})". For example GVariant *args = g_variant_new_parsed("({'Transport': <%s>},)", "le");
for the SetDiscoveryFilter and GVariant *args = g_variant_new_parsed("({'offset': <%q>},)", offset);
works fine. Upvotes: 3
Reputation: 18452
You should not use the Bluez C functions at all. Instead use the newer GDBus functions. At https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/adapter-api.txt you can find out how to scan. Call StartDiscovery. The DBus devices will then be added as they are discovered. Listen to the interfaces-added signal to detect new devices. It's strange that you say no devices are detected, since it should work.
The ReadValue method should work. Are you connected to the device while you read?
Also check using hciconfig that the hci layer is UP. If nothing works, you can always run "sudo btmon" to get a capture of what's going on.
Upvotes: 2