My android device is connected to a BLE dongle. The BLE Dongle is sending me messages for example A at 20 to 40 milliseconds of interval. I am getting messages in onCharacterticChange method. I am modifying the messages to for eg. to B. I am calling Bluetoothgatt.writeCharacterstic(characterstic) method at 20 to 40 millisecond interval to send messages B back to BLE dongle. I am sending near about 10,000 messages to BLE Dongle. Some times instead of B ,the dongle is getting message A. That is very strange i don't know what is happening in the background?? How to prevent that. I hope anyone have answer to that.
Related
I am working on a BLE app. I am through to establishing communication between Mobile app (CENTRAL - BluetoothGattClient) and PERIPHERAL (GATT SERVER) albeit not neatly.
PERIPHERAL has one service which in turn has single characteristic on which CENTRAL has enabled notification. Read/Write from both sides happen through this characteristic
Here is the complete flow of communication from CENTRAL (Mobile) side
Problem 1
Sometime while receiving multiple packets from PERIPHERAL, I receive read notification - 'onCharcteristicChanged()' before I finish writing ACK (STEP 9) i.e. onCharcteristicChanged() is called before onCharctristicWrite().
In this scenario though I issue bleGatt.readCharacteristic(charac) but onCharactristicRead() never gets called. CENTRAL gets stuck. It is unable to read while waiting.
Problem 2
Sometime, while sending ACK, after issuing bleGatt.writeCharactristic(charac), onChactristicWrite() is not called hence ACK is not received by PERIPHERAL and communication stops.
Problem 3
Overall communication is very slow. It takes > 400ms to write one chunk (<=20 bytes) of data.
Is there any better strategy to sync Read/Write properly? I tried to do it by using BluetoothGattCallbacks but as explained it is not working properly.
What can be done to increase the speed of communication?
Both READ and WRITE is happening in same thread.
I have tested this on Moto E (Marshmallow), Moto G5 (Nougat) and Samsung S6 (Lollipop). The behaviour is consistent across devices.
My PERIPHERAL device is nRF52840.
Thanks
The easiest way to make sure your GATT communication works correctly is to use a queue for the BluetoothGatt object, since only one GATT operation can run at a time. That's why it doesn't work when you for example call readCharacteristic before the onCharacteristicWrite is called by the system.
The reason you get the notification before the write response is because the peripheral sends the notification before the write response.
What you can do to speed up the communication is to use Write Without Response instead of Write With Response. That way multiple packets can be sent in one round trip. The onCharacteristicWrite will then be called immediately (as long as the internal buffers are not filled up). Just be aware of https://issuetracker.google.com/issues/37121017.
When I try to receive and transmit BLE beacons at the same time Android device (5.0, 5.1, 6.0) transmits beacons only and doesn't scan. How can I do it at the same time. Please, give me simple code example. With only receiving or only transmitting there are not problems. I use android-beacon-library-2.11.
Is not possible to receive and send data through BLE at the same time: you need to implement some kind of read/write operations list and execute them sequentially, one by one.
I am trying to send 10 bytes of data, every 30milisecond,s between 2 android devices using bluetooth low enegry notifications. The goal is to achieve low latency communication and there is no interest in low energy.
You can check the results in the Delay graph(Y field = delta time between packets). The first 10seconds the communication is being perfomed good enough. (The interval between the packets is max 30-40ms). However after the 10th second, the intervals are either extremly high or extremely low.
This is probably happenning due to non strict connection interval parameters. You can check a sample of hci_events that shows clearly the slow down is caused by the hci_events.
I have tried to configure the parameters of the connection, calling from the master the function
requestConnectionPriority
However, it didn't change anything on the result graph. I also check the packets using wireshark and findout that the master didn't even send a request for configuring the connection interval. I also tried another configuration request with
requestMtu
with exactly the same results, no update packets was send from the master.
So, there are 2 questions that show up from this observations.
Has ble a timeout in the 10th second in order to ensure low energy consumption? If so, how can I disable it?
Is some thing wrong calling requestConnectionPriority, from the android 6.0.1 with the role of the central(master)? Can you give me a simple example on how is being called properly?
Note that requestConnectionPriority is called right after the connection being establish in the onConnectionStateChange of the BluetoothGattCallback.
The device that has role of a slave(server) is running (Android 5.1.1) and the master(client) is running (Android 6.0.1).
Thanks a lot!
IMPORTANT UPDATE: It's crucial to mention the way the connection is being initiated between the devices.
The central device calls device.connectGatt, where device is BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address). Address is a hardcoded string, the peripheral's public mac address. You can check logcat logs and also hci logs.
I have also tried connecting with the legit method (peripheral advertising and connect to scanned random address), but I get an error 'initiate direct connection fail, topology limitation'. You can check logcat logs and also hci logs.
Has ble a timeout in the 10th second in order to ensure low energy consumption? If so, how can I disable it?
No
Is some thing wrong calling requestConnectionPriority, from the android 6.0.1 with the role of the central(master)? Can you give me a simple example on how is being called properly?
I'm not aware of any bugs regarding requestConnectionPriority. But you could try to execute that method after the onServicesDiscovered callback. Android temporarily changes connection interval to 7.5 ms during the GATT service discovery so it might be confused if you don't wait until the service discovery is completed.
Regarding requestMtu, make sure you execute that method while there are no other GATT operations pending (otherwise it won't work).
One additional tip is to use an air sniffer and not only look at the hci logs.
I have a question regarding the bluetooth LE protocol.
I have an Android Device and a peripheral device.
Looking at the transmission with a sniffer and wireshark there is +/- every 40ms an empty PDU message. As I understood the protocol this means the connection interval those device chose is 40ms.
For testing I am using a simple "UART" application where the android device enables the notification on an antribute of the peripheral device and gets notified whenever the attribute changes.
Now, if I "send" multiple 20 byte packets through this setup, wireshark shows me, that those value notifications are just about 7-10 ms apart. Each Notification contains 20 Bytes
Does that mean, that the connection interval does not apply for notifications and that each notification can hold max. 20 Bytes?
Thanks & Greetings!
There is one connection event per connection interval. In each connection event multiple packets can be sent directly after each other. When no side has anything left to send, the connection event is closed and next exchange will occur at the next connection interval point. So yes, many notifications can be sent in one connection interval.
I'm looking for a way to detect the disconnection of a Bluetooth device immediately after it has happened (2 second max), typically in a "device too far" scenario or Device battery is dead. Currently I can detect it with a BroadcastReceiver by getting a BluetoothDevice.ACTION_ACL_DISCONNECTED, but it takes about 16 to 20 seconds to fire.
Is there any way to get notified in 2 seconds Max.
I used BroadcatReceiver but it is not fast enough to get alert in 2 seconds Max, so is there any other kind of approach available to get notification quickly that bluetooth is disconnected.
I use this createRfcommSocketToServiceRecord(UUID); to connect a paired device and i am bound to use it using UUID.
I have visited a lot of links regarding this issue, but no one matches with my needs.that's why any help would be appreciated.
thanks.
I think the only way you can reliably sense loss of connection quickly (within two seconds) is via your own application protocol that you use over the Bluetooth connection. For example, your application protocol might implement a heartbeat that occurs every 500ms. If you don't see a heartbeat within two seconds then you could trigger your own event.
Bluetooth is a socket-based stream protocol that is designed to work over an unreliable medium (i.e. radio), and as such has to tolerate errors in (or loss of) packets. For this reason it will take significantly more than 2 seconds before your Bluetooth stack declares it has given up and disconnected the device, as you have found.
I have an application on Play which is designed to talk with an automotive ECU via Bluetooth and my strategy for sensing disconnection is exactly as I suggested in my first paragraph.
Update 20th June 14
I see in your bounty comment and also your comment below that you're asking for a code example, but it's kind of difficult for me to provide one without knowing anything about the application protocol that you're running over the socket connection. Or to put it another way, what exactly is it about my first paragraph (i.e. the heartbeat suggestion) that you do not understand or cannot create code for yourself? The concept of using a heartbeat really is quite simple. You would define a certain message type in your application protocol that represents a heartbeat message. One end of the connection sends this heartbeat message periodically, say every one second. The other end of the connection checks that this heartbeat message is received every second or so and drops the connection after a two-second time-out. It is impossible to be any more specific than that, because I can't see your existing code and I don't know what kind of messages you are currently exchanging over the socket.
After nothing work around!
I got two things to get my work done.
I need to check that is my Bluetooth socket is not in use(Sending Receiving) till 2 to 5 sec I disconnect that and when user wants to send data to the receiver device I connect that again.
Or I'll try to connect the socket after 2 to 5 sec so that if it is not ready to connect means it is already connected, else it will be connected and I refresh the previous socket references.
but first option is more valuable to work perfectly in my problem.
This is a problem with old bluetooth and more hardware than software.
If you want to notice that the connection is broken you need to do polling (a heartbeat), something like "are you alive? are you alive?"... This is bad for battery so... the users will finally uninstall your app.
I recommend you to change to BTLE (bluetooth low energy), devices like Nexus 5 has this.
With BTLE you have a proximity profile which can tell you the quality of the signal, so, you can guess the distance (near, far, out of range) and therefore you can also tell if the devices are disconnected.
Another nice point is that if the devices are out of range but one is again in range you could get noticed as well, so this is really nice for apps to open doors by proximity for example.
Check this:
https://developer.bluetooth.org/TechnologyOverview/Pages/PXP.aspx
In the other hand Apple has invented the concept of iBeacons, devices that are distance aware, and the good thing is that there is also an implementation of iBeacons for Android:
http://developer.radiusnetworks.com/ibeacon/android/