Reading stream data from Bluetooth Low Energy device - android

I am having some difficulties with Bluetooth Low Energy on Android. I have closely done the guide I linked, as well as checked the full example code. I have a BLE device I need to connect to and retrieve data frames from. The documentation at one point dictates to
Discover/Enable service: Service UUID UUID1, Characteristic UUID UUID2
Once this has been executed correctly, the device should start streaming frames of 20 bytes formatted in a particular way.
Searching for the device, connecting to it and discovering services on it I have no problem with. But then I'm stuck. To get the services, BluetoothGatt's method getServices() is called. This returns a list of BluetoothGattService's, which on their part also contain a list of BluetoothGattCharacteristic's. Obviously the BluetoothGattService's UUID must be equal to provided UUID1, and BluetoothGattCharacteristic's UUID to UUID2. But I do not know how to 'enable' this service with certain characteristic.
My documentation also does not mention descriptors. I have checked and there is only one descriptor in the UUID2 characteristic. So now I have everything one could possibly need - Service UUID, Characteristic UUID and Descriptor... But how do I read the data?

You can iterate over all found characteristics and get the BluetoothGattCharacteristic object with UUID1 and UUID2. Use "UUID.fromString()" to convert a string representing the UUID to a UUID object, which than can be used with ".equals" to compare with "characteristic.getUuid()".
If I've understood you correctly, you want to read some data of a characteristic. When you call "connectGatt" on your BluetoothDevice, you get an object of type "BluetoothGatt". Use this gatt object after discovering the service and characteristics to call "readCharacteristic()" on it, passing the desired BluetoothCharacteristic as argument.
I hope I could help and let me know if I should clarify my answer
Linard

Related

Obtaining RSSI from Scan Request / Scan Reply packets

I'm new to android development and I'm writing a APP as proof of concept for a research project using the BLE Google API. I have two android phones, one of which is advertising some beacon X that carries a scan response Y, while the second phone is scanning for advertisements. I would like to access the RSSI values corresponding to the ScanRequest and ScanReply packets that follow the advertisement.
During device to device communication, when the overwritten onScanCallback method is called on the second phone, I can only obtain a single RSSI value by calling result.getRssi() on the passed ScanResult. Furthermore, as expected, the corresponding ScanRecord provides two ServiceUuids by calling the record.getServiceUuids, where the first UUID corresponds to the advertisement itself, and the second one to the programmed scan reply.
Until now I haven't found any public methods to recover the RSSI of the ScanReply, is there some other way of accessing this second RSSI? And the same applies to the RSSI of the ScanRequest that is automatically sent by the listening device, is there a way of recovering it?
Thanks a lot in advance,
Ivan Morales
The RSSI in the scan callback already corresponds to the RSSI in the scan response packet, not the advertising packet. Android's Bluetooth stack throws away the RSSI value for the first packet. Why do you need it anyway? It should be more or less the same as the first packet since both packets are sent within such a short interval.
You can't get RSSI for a scan request. This info is not sent from controller to host if you read the HCI standard. Even if the Bluetooth stack would listen to "LE Scan Request Received event", that event doesn't include RSSI.

BLE, the more characteristics and services the more slowly

BLE and Android, the more characteristics and services the more slowly
Following problem:
I’m working on a project with android (5.0+) and a Nordic BLE chip (NRF52832) to receive values from the chip on the android device.
(I don’t use third party packages)
Connect, readout the services and the characteristics works well and fast, but:
As soon as I set more characteristics (in 2 services) on notify, the values arrive the device very slow, for example:
Notify 1 characteristic = 50ms/value
Notify 1 service 6 characteristic = 150 – 200ms/value
Notify 2 service, 10 characteristics = 400-600ms/value`
RequestConnectionPriority won’t solve my case.
Does anyone have a solution statement or already a solution?
It is a know problem that using multiple services and characteristics can slow down the communication between a BLE center and a peripheral.
Furthermore, each characteristic has an overhead cost in terms of memory consumed on the device.
A solution to this problem is to minimize the number of characteristics you're using.
To do so, you could for instance use only one characteristic and dedicate one octet of the characteristic packet to storing the command id or info type you're sending or receiving from the device.
The same characteristic can then be used to send various command to your device, or to request various type of info from the device.

UUID's have to be distinct for service , characteristic and descriptor?

I am trying to make a client-server connection with the server containing one service with one characteristic which contains one descriptor. I've made the service, characteristic and descriptor have the same UUID , but when I try to write on the descriptor/characteristic (in the android app) a pop-up appears that tells me , bluetooth has to shut down becouse of some problem (not known). Is there any condition that the UUID's have to be distinct ?
The "UU" of UUID means "Universally Unique". The UUID is describing the type of data, though, so you can have 2 characteristics with the same UUID if both are providing the same sort of data. (ex 2 thermometers) I think descriptors are supposed to have UUID's dictated by the standard (so you know they're descriptors).
So, the service, characteristic, and descriptor should all have different UUID's.

Android BLE - determine characteristic's stored value type

My issue is with lack of ability to determine the type of the value, that read BLE characteristic has been storing. According to bluetooth spec. https://www.bluetooth.com/specifications/assigned-numbers/format-types those types are predefined by the standard and therefore GATT client should be able to read them.
My app is an attempt to create generic GATT client with ability to read any service and any characteristics it stores. For this I must have some universal way to read the type of characteristic, so that I am able to read it properly. For this I lack BLE API, that would allow this
I think simillar question is asked here: How to get BluetoothGattCharacteristic value format type? but question did get no answer.
Unfortunatelly current workaround would be to map UUID of specified in bluetooth characteristic, with the stored value's type. This solves lots of daily cases, but still is not enough to create completely generic GATT client.
Ok, I found the answer. For the people having simillar issue the answer lays not in BLE android API, but in bluetooth GATT specification.
It turns out, that some descriptors are mandatory and one of this is characteristic presentation format, specified here:
https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
there we can find the "hard coded value type", which is 8bit value and enum, which represents this value as the type. Based on this value we can deduce the characteristic's value type and read it properly.

How do you know whether the result of "onLeScan" is the device you are looking for?

So I have a known BLE device that I want to connect to and interact with.
However my query is when results are being returned in the method from this reference http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.LeScanCallback.html how can you check that the device returned in the callback is the one you want to interface with?
Sorry no code examples as I am on my phone.
You can get Mac Address:BluetoothDevice.getAddress()
also you can get device name,but maybe it is null.
also fliter it by the rss value is max.
By examining the scanRecord byte array you could obtain additional information about the device.
An advertisement is very limited in number of bytes you can send out, you could provide more info about your device if you enable active scan. Your scanner obtains then a scan response packet, whichs is just like the normal advertisement packet but with more room in it.

Categories

Resources