Detect bluetooth FW hang in bluez stack - bluetooth

I am trying to implement an application using bluez.
The issue is :
If sometimes the Bluetooth controller Firmware goes into bad state, my application hangs.
There is no way to recover, except through a power reset.
The solution I can think of is implementing a timer after sending the hci command to the controller.
Is there any preferred way to do it in bluez user space?
Or does this have to be handled at the application layer only?

Related

BlueZ: Removing bonding with BLE device does not work

We've got a use case in which a BLE connection is used to do the basic configuration of an embedded device via an Android app (later also via an iPhone app). The embedded device runs Linux and thus uses BlueZ as Bluetooth stack.
Using the DBus-API of BlueZ, bonding is made possible by making the device pairable, discoverable, and activating advertising. After bonding the apps can access the GATT services and characteristics
(which require bonding to be read/written) on the embedded device.
After the setup is done the bonding of the device (running the app) that managed the setup process, is supposed to be removed. In order to do that we call RemoveDevice() of org.bluez.Adapter1.
The BlueZ documentation states the following
void RemoveDevice(object device)
This removes the remote device object at the given
path. It will remove also the pairing information.
Still the app is able to access the GATT characteristics afterwards.
If bluetoothctl is used to check the list of paired devices, the list is not containing that device anymore though. Before calling RemoveDevice() the bonded device was visible there.
If bluetootd is stopped and restarted the app is no longer able to read/write the GATT characteristics, but needs to re-bonded before doing so.
I can neither find any further information in the BlueZ documentation nor can I find anything about this topic searching anywhere else.
Is this intended behavior or is this a bug? Does "remove pairing information" also mean "remove bonding information"? If this is intended behavior, how do we properly terminate bonding with a device?
Should I use the BlueZ Management API instead of the BlueZ API? I'm not sure about this as multiple source state that the DBus-API is the way to go.
RemoveDevice() indeed removes the bonding information as well. So you have to disconnect first and then call RemoveDevice(). The next time you connect the bonding information will be gone.
However, note that if you only make use of encrypted characteristics, you can still connect and discover services. Only once you start reading/writing the encrypted characteristics will Bluez check if you are bonded.

How to setup Bluez 5 to ask pin code during pairing

I implemented the org.bluez.Agent1 interface using QDbus and I would like to set a fixed pin (that I will provide to the users) in order to authenticate all the pairing request and reject them if the pin is wrong. The agent capabilities should be "NoInputNoOutput" because the project will be deployed on the RaspberryPi 3 without keyboard or display. Is there a way to deal with this? Thank you
You should not initialize the capability as "NoInputOutput" for fixed key pairing. NoInputOutput means there is not display and there is no keyboard/UI possible for this device. Mentioning this capability for your Agent when registering with BlueZ means, instructing BlueZ (bluetoothd) not to call any Agent API for authentication.
This is typically useful to autopair without any manual intervention. You can see this sample code, which uses NoInputOutput capability to connect the device without any intervention.
What you need is "DisplayOnly" capability to instruct BlueZ to call "DisplayPinCode" or "DisplayPasskey" based on SSP support of your device.
You can implement DisplayPinCode/DisplayPasskey in your Agent to reply constant PIN always. So the Bluetooth device which tries to connect can use the same constant PIN for pairing.
Here Display Pin /Passkey is just the naming convention or hint to Agent developers to write wizard/UI or any form of display operations. But you can completely ignore the displaying operation and reply with static/constant 6 digit key for pairing.
Typically this Agent API is called by Bluez (in rasperry pi) when the device (iPhone/Android mobile/any bluetooth capable device) trying pair calls "RequestPasskey" or "RequestPinCode" from the device end.
We had the same issue in a project, and i moved on LE device do to the fact that apple device are only capable to connect to LE device for "safety" reasons.
I don't have that much ref to that but if this could help you in your researches.

Qt Bluetooth Low Energy Multiple Connections

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.

Bluez auto reconnect devices

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?

Simulate a USB Device for Automation

I have to simulate a USB Device for automation and testing purposes (in Linux). Original driver/application for this device uses “libusb” to communicate with it.
I don’t have much experience in Linux and Simulation, after some searching I have understood that I need to write a kernel level driver and an application in user-space to simulate that device. Is this right? If Yes, How can this be done?
Thanks in Advance.
Finally implemented it by modifying "libusb", modified it to send and receive usb transfers from message queue instead of usbfs. Programmed my simulator to create libsub type transfers and send/receive them using message queues as well.
Simulator now interprets the incoming transfers and sends it to a command parser, which sends request/message to automation system using sockets in a specific format. Automation system sends it's instruction by sending to command parser using socket. This socket invokes method specific to each request in simulator, Now simulator forms an appropriate transfer structure and passes to device plugin (via libusb) through message queue.
I think what you're looking for would be called a virtual USB device. Currently there is nothing in standard Kernel.Some virtual machine provides USB emulation.e.g. KVM provides USB emulation. There is framework gadget in which might look for your solution.
Or find something in Linux USB project
Thanks,
Abhijeet
The usb-vhci project could be of use if you want the device to be presented to the kernel in the same way as real hardware.

Resources