I am writing a library in C/C++ for a Bluetooth low energy device. So far I have been using the D-Bus interface exposed by Bluez and been able to discover, connect and communicate with the device.
However, when the device disconnects either due to a link failure or it being out of range, reconnecting to it is not trivial. Ideally I would like to be able to create pending connections to all disconnected devices, but Bluez doesn't seem to support that. It seems that Bluez only supports one simultaneous connect call, which timeouts after 15-20 seconds.
A solution would thus be to listen for advertisement packages, and connect when a known device is detected. The good people on #bluez told me that this was already implemented, and the way to do it is to register an object that implements GattProfile1 with the GattManager1 RegisterProfile method. Trying this gave no result, the device stays disconnected after a link failure. It is also very poorly documented, so there is a good chance I have missed something.
My questions are: Is this the right solution? Will it provide a seamless and fast reconnections? If it is, what can be wrong?
If you wish to reconnect to a single bluetooth device, you can monitor the connection state by receiving org.freedesktop.DBus.Properties.PropertiesChanged, and calling org.bluez.Device1.Connect to reconnect when necessary. Since this will timeout, you can put Connect() inside a loop which you will exit only when the org.bluez.Device1.Connected property is true.
Has the original author managed to do this yet for multiple devices by implementing GattProfile1?
Related
Usb libraries always support setting timeouts on operation with device. And this is important feature for soft which works with usb devices, because that's how you can understand that device don't answer to your command. I look through WebUSB Api and look's like it's not support timeouts at the moment.
Is it true? Is the only way is to manually start timeouts before every usb operation, and stop timeout after operation success?
WebUSB does not currently support transfer timeouts or aborting transfers because after surveying the various platform APIs for USB it did not seem possible to implement them in a consistent way. Ideally it would be possible to cancel a transfer by removing it from the USB controller's transfer schedule. This is possible on Linux with the USBDEVFS_DISCARDURB ioctl and timeouts are supported on macOS using ReadPipeAsyncTO() and similar functions. On Windows however the only way to cancel a transfers is to call WinUsb_AbortPipe() which affects all pending transfers on the pipe, not just the one that timed out.
If you need to react to a device not replying to a USB request in a timely fashion then doing so manually with setTimeout() and clearTimeout() is the best option. Keep in mind that USB transfer itself will remain active and could complete at a later time.
I would like to support multiple (at least 2) simultaneous BLE connections to Bluez as peripheral with one adapter. I believe it is technically possible since many embedded platforms support this (Silabs, Nordic).
Currently, with the first connection GATT advertisement stops altogether until the connection is dropped again. Is there some way to keep advertising?
Furthermore, if this is even possible, I currently don't see a way to use attribute notifications to a specific connection. One uses the dbus PropertyChanged method for emitting characteristic value notifications, though it seems as if there is no way to specify to which remote devices to send it to. Is there a way to notify only a specific connection of Value changes?
I can do the above on a Silabs EFR32 without issue but would like to get the same on embedded Linux.
Thank you kindly
I am using two BLE devices for connection to establish using bgapi library. After sometime both devices disconnect abruptly at the same time. I don't know where to look into as I can't see any errors that is logged.
Connection for one device is working fine but issue is with the connecting two devices.
Most importantly it is not happening every time.(Out of five tries devices are disconnecting once)
I tried udev blacklist. I thought modem manager might be interfering but of no use.
I know that bluetooth uses hoping, and because of this difficult to intercept traffic.
Сan i put my dong into monitoring mode?
If for example are 30 devices nearby, and i will always listen just one bluetooth channel, and my dongle works in monitor mode, should i get sometimes some data?
Can i use for these purposes Hcidump or tcpdump?
If I understand correctly, if bluetooth device does not have a password, i can directly interact with its services(with hcitool and tmux).?
I read that i can watch the battery level, device name, and other information.
PS: sorry for bad english.
It is possible to monitor traffic between Bluetooth devices but I am quite sure that your default laptop dongle is not capable of doing that.
Before establishing connection between two Bluetooth devices, they send connection request/response packets on primary advertising channels (37th, 38th, 39th channel). You need to capture these packets to learn hopping pattern, connection interval and etc. After receiving packets, you can monitor insecure Bluetooth connections. However it is hard to monitor 30 device simultaneously because you need to make time division between each connection.
Let's answer your questions.
It might be possible but you need to write driver level code.
It might be possible. As I mentioned, it is good approach to capture connection request/response packets before monitoring devices.
I have no idea about these tools.
To manipulate services, you need to know service handle and duplicate GATT client's mac address. I am not sure that, this method will work.
Qt: 5.10,
Linux Ubuntu 17.10,
Bluez 5.4x
and I´m using QBluetooth to connect with multiple Bluetooth Low Energy Devices. Everything works fine for one Connection. But when I connect to a second Device with QLowEnergyController::connectToDevice() I get the following error and the first Connection gets aborted:
qt.bluetooth.bluez: Cannot connect due to pending active LE Connections
qt.bluetooth.bluez: void QBluetoothSocketPrivate::_q_readNotify() 21 error: -1 "Software caused Connection abort"
After that the second connection gets established.
I`m using one instance of QLowEnergyController in Central Mode per Connection.
After a Research I think it should be possible to create multiple Connections to BLE Peripherals with the Bluez Bluetooth Protocol Stack. But I´m not sure if QBluetooth support this Feature...
Does anybody know something about multiple LE Connections with QBluetooth?
Is this the right way to establish a second Connection?
Does somebody know a good Workaround?
Thanks for your help!
The problem isn't BLE, but its Qt implementation. The documentation says that any attempt to connect simultaneously to two BLE devices using QLowEnergyController will fail. Check it there: http://doc.qt.io/qt-5/qlowenergycontroller.html ; Section "Detailed Description", paragraph 5:
"BlueZ based Linux cannot maintain two connected instances of QLowEnergyController to the same remote device. In such cases the second call to connectToDevice() may fail."
According to this, it should be possible to establish connexion to two different remote devices using two instances of the class, but it simply doesn't work. If you keep on reading the documentation, you'll find out that " This limitation may disappear at some stage in the future.".
I tried a workaround by disconnecting from the first device before connecting to the second device (both TI SensorTag), but since I had to re-discover the services and re-enable the sensors (see disconnectFromDevice() in the documentation) every time I would re-connect the program became way too slow.
If you want to connect to two devices using Qt, you have to use the Bluez API through the D-Bus with Qt's D-Bus classes.
Edit:
I managed to connect to multiple devices using D-Bus classes. The architecture of my program isn't much more complicated, only the syntax got a little more tricky. The only big issue was the BlueZ version: the D-Bus interface changed a lot between 5.3x (default Ubuntu 16.04) that doesn't support Low Energy (experimental...) and later versions. I think that's the reason why Qt's D-Bus Bluetooth hasn' been enabled yet. Since BLE isn't flagged as experimental since BlueZ 5.42, you should be fine using D-Bus with your current version. For the record, I'm perfectly fine using D-Bus with Raspbian's default 5.9 BlueZ.