Android BLE peripheral disconnects with status code BLE_HCI_INSTANT_PASSED(0x28) - android

My application is able to connect to the BLE peripheral(which is an OBDII/J1939 device) device successfully.
2018-01-24 14:58:38,413 INFO LogUtil - GATT Server Status = (0) : BLE_HCI_STATUS_CODE_SUCCESS(0x00)
2018-01-24 14:58:38,414 INFO LogUtil - GATT Server New State = (2) : STATE_CONNECTED
2018-01-24 14:58:38,414 INFO LogUtil - Connected to GATT server.
Application started communication with the device but after some time it received GATT server disconnection message in onConnectionStateChange in callback implementation of BluetoothGattCallback . Below are the logs from application:
2018-01-24 15:07:46,396 INFO LogUtil - GATT Server Status = (40) : BLE_HCI_INSTANT_PASSED(0x28)
2018-01-24 15:07:46,397 INFO LogUtil - GATT Server New State = (0) : STATE_DISCONNECTED
2018-01-24 15:07:46,398 INFO LogUtil - Disconnected from GATT server.
Not able to find any reason behind BLE_HCI_INSTANT_PASSED status code.
Any help on this will be helpful.

When data is being transmitted over BLE, data transfers can only start at sync points in time known as "connection events". At the BLE link layer there are couple special requests that can be made which are relative to these sync points. They are:
LL_CHANNEL_MAP_REQ - A request to change the BLE channels being transmitted on. Bluetooth chips will change the channel map based on the noise in the environment to try to limit packet drop.
LL_CONNECTION_UPDATE_REQ - A request to change the frequency of "connection events" (known as the "connection interval"). This is done to achieve better throughput/latency or save more power.
Each of these Link Layer requests when sent over the air contains an "Instant" to change. The "Instant" is the "connection event" in the future to apply the change.
At the Link Layer, BLE is reliable. This means each Link Layer packet must be ack'd by the other side. In a noisy RF environment, it's possible a link layer packet may require a couple retries to actually send. This means the packet could arrive many "connection events" after originally intended.
If one of the packets mentioned above is received after the "Instant" the changes were supposed to be applied, by definition the BLE chip must disconnect with reason 0x28 (Instant Passed)
For additional details on the topic, the Bluetooth Core Specification available from the Bluetooth SIG website is a good reference:

Related

How to write characteristics for bluetooth gatt service for two channels without getting disconnected(state 133)?

I've a bluetooth gatt service and two channels to write
bluetoothGattService = gatt?.getService(UUID.fromString(ble_gatt_service_uuid))
mTxCharacteristic1 = bluetoothGattService.getCharacteristic(UUID.fromString(txCharacteristics1))
mTxCharacteristic2 = bluetoothGattService.getCharacteristic(UUID.fromString(txCharacteristics2))
Now I have onCharacteristicsRead(), onCharacteristicsWrite(), and onCharacteristicsChange()
I connected with the ble device
When I write on mTxCharacteristic1 characteristic then ble works well
But whenever I write on mTxCharacteristic2 characteristic then ble gets DISCONNECTED
// function1
mTxCharacteristic1.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
mTxCharacteristic1.value = chunk
gatt.writeCharacteristic(mTxCharacteristic1)
//function 2
mTxCharacteristic2.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
mTxCharacteristic2.value = chunk
gatt.writeCharacteristic(mTxCharacteristic2)
How to resolve this?
Everytime it is getting disconnected whenever I send data using 2nd characteristics, I'm only able to connect with ble again only when I restart my android device.
I tried:
gatt.beginReliableWrite()
gatt.setCharacteristicNotification(characteristic1,true)
gatt.writeCharacteristic(characteristic1)
gatt.executeReliableWrite()
gatt.beginReliableWrite()
gatt.setCharacteristicNotification(characteristic2,true)
gatt.writeCharacteristic(characteristic2)
gatt.executeReliableWrite()
nrf connect app showing (TX(1) and unknown_characteristic(2))
still getting the same disconnected with gatt server issue with state 133.
Just made this simple writeCharacteristics instead of reliableWrite on doing this disconnection and no repairing issue resolved
gatt.writeCharacteristic(characteristic1)
gatt.writeCharacteristic(characteristic2)
I was have 8 byte of packet data where I sent null which I found on debugging
expected was 19 byte array and I was sending only 11 packets (8 missed)
due to this it was giving me error and getting disconnected with state code 133

BLE Device dissonect after receive Notifications (BLEGattException Status = 0x8)

My BLE server permanently measures a sensor value and sends a notification with 20 byte user data after each measurement. The goal is to generate as much throughput as possible.
On the client side, the value sent by the server is received and processed.
rxBleConnection.setupNotification(setDescriptorEnableNotification(characteristic))
.flatMap(notificationObservable -> notificationObservable)
.observeOn(Schedulers.newThread())
.buffer(1)
.subscribe(bytes -> {
onNotificationReceived(bytes, buffer);
} , throwable -> {
// Handle an error here.
onNotificationSetupFailure(throwable);
}
);
If I set the Connection intervall to 11.25ms, I receive all values. However, if I set the connection interval to 30ms, I receive a few values ​​and then the connection is closed.
In the Android Log i see the followed message:
BleGattException status=8 (0x8),
bleGattOperationType=BleGattOperation{description='CONNECTION_STATE'
Why is the connection interrupted and what is the trigger?
With the help of a BLE Sniffer this is not recognizable. The set connection parameters are accepted and the transfer begins. Suddenly the transmission ends and the error message appears.
Update:
BLE Sniffer screenshot has been added:
30ms, this is connection interval you set in server or android?
Btw, on android you can set speed mode
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
mBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
}
Error 8 means the connection timed out. There is nothing wrong on the Android side. The problem is with the communication between the two Bluetooth controllers. If you have a sniffer then you should be able to see who is the one that fails to send packets.
Here is an Image from BLE Sniffer.
BLE Sniffer
I have the similar problem. On Android 7.0 there were two ways to keep connection:
1) If devices are bonded and there is a charachteristic reading callback with constant thread of packets. If there are no packets by some time, then connection fails.
2) If devides are not bonded, but I do TXCharacheristic.read every few seconds. If don't do that some time, then connection fails.
But now in Android 7.1.2 this way doesn't work.
May be the first way will work for you.
On your Android device you should make bonding, on your kit you should handle this bonding.
On Nexus 6P and Samsung S7 it doesn't work anymore, but I didn't try it on the other devices.
I suppose, you have min connection interval 7.5 on your BLE kit, but now it is deprecated on Android.
Try to set min connection interval to 11.25 on your BLE kit and set connection priority
gatt.requestConnectionPriority(CONNECTION_PRIORITY_HIGH);
where CONNECTION_PRIORITY_HIGH = 1
in onConnectionStateChange.
It had worked for me when I had changed min connection interval in my nordic from 7.5 to 11.25.

BLE: when writing characteristic, getting status as 133 in onCharacteristicWrite

I'm trying to setup BLE client-server comm on android devices.
From the server side, I could advertise and see connection updates successfully. On the client side, I could connect to the server , discover its services and characteristics. However, when I try to write the characteristic, I'm receiving
status 133 in onCharacteristicWrite()
I'm not sure why it is happening..!! Need some help..
I've tried to do the following, but they didn't make any impact:
-> adding setWriteType
-> Changing the UUID to a private one
Do I have to get permissions before writing at client side?
I would start from checking the property of the characteristics.
Checkout this thread for more information.
If the above actions does not help then try to verify that the attributes of the BLE server side are correct. For example: if you just connecting (with no pairing or bonding) then since it's an non-encrypted link the attributes of the characteristic shouldn't include any encryption enabled.

BLE Number of Packet per Connection Interval in Wireshark

I need to know exactly how many packets per interval my BLE can handle. The peripheral, as per its datasheet, handles 6 packets per interval, but I have been unable to find out how many packets the Central can handle. The Central device is a Motorola Moto G (generation 2), running Android 5.0.2.
By examining he btsnoop_hci.log file I have been able to identify multiple connection parameters, such as the connection interval (7.5ms in my case). My questions is wheter it is possible to determine how many packages can be exchanged in a single coonection interval, by examining the negotiation packets in Wireshark.
In the spec, there is no negociation about the max number of packets in a Connection Event. A connection event can simply last for at most (ConnectionInterval - 150µs) (See 6.B.4.5.1).
Limitations, if any, are in the PHYs, at either side. Most HCI firmwares limit to 4-5 packets per connection event, per direction.
It is up to the controller on the master side to decide how long the connection event should be open (as long there are more packets from any side). The slave has nothing to say about this.
For a central host, when creating a connection as well as when updating connection parameters there are two HCI parameters Minimum_CE_Length and Maximum_CE_Length. These are informational parameters that indicate how long it should keep its connection event open. If these are set to high numbers, the controller will have the connection event open as long as possible.
Sadly, Android set these parameters both to 0 which means most controllers will restrict the connection event to only 3 or 4 packets.

Bluetooth RFCOMM / SDP connection to a RS232 adapter in android

I am trying to use the Bluetooth Chat sample API app that google provides to connect to a bluetooth RS232 adapter hooked up to another device. Here is the app for reference:
http://developer.android.com/resources/samples/BluetoothChat/index.html
And here is the spec sheet for the RS232 connector just for reference:
http://serialio.com/download/Docs/BlueSnap-guide-4.77_Commands.pdf
Well the problem is that when I go to connect to the device with:
mmSocket.connect(); (BluetoothSocket::connect())
I always get an IOException error thrown by the connect() method. When I do a toString on the exception I get "Service discovery failed". My question is mostly what are the cases that would cause an IOException to get thrown in the connect method? I know those are in the source somewhere but I don't know exactly how the java layer that you write apps in and the C/C++ layer that contains the actual stacks interface. I know that it uses the bluez bluetooth stack which is written in C/C++ but not sure how that ties into the java layer which is what I would think is throwing the exception. Any help on pointing me to where I can try to dissect this issue would be incredible.
Also just to note I am able to pair with the RS232 adapter just fine but I am never able to actually connect. Here is the logcat output for more reference:
I/ActivityManager( 1018): Displayed activity com.example.android.BluetoothChat/.DeviceListActivity: 326 ms (total 326 ms)
E/BluetoothService.cpp( 1018): stopDiscoveryNative: D-Bus error in StopDiscovery: org.bluez.Error.Failed (Invalid discovery session)
D/BluetoothChat( 1729): onActivityResult -1
D/BluetoothChatService( 1729): connect to: 00:06:66:03:0C:51
D/BluetoothChatService( 1729): setState() STATE_LISTEN -> STATE_CONNECTING
E/BluetoothChat( 1729): + ON RESUME +
I/BluetoothChat( 1729): MESSAGE_STATE_CHANGE: STATE_CONNECTING
I/BluetoothChatService( 1729): BEGIN mConnectThread
E/BluetoothService.cpp( 1018): stopDiscoveryNative: D-Bus error in StopDiscovery: org.bluez.Error.Failed (Invalid discovery session)
E/BluetoothEventLoop.cpp( 1018): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/1498/hci0/dev_00_06_66_03_0C_51
I/BluetoothChatService( 1729): CONNECTION FAIL TOSTRING: java.io.IOException: Service discovery failed
D/BluetoothChatService( 1729): setState() STATE_CONNECTING -> STATE_LISTEN
D/BluetoothChatService( 1729): start
D/BluetoothChatService( 1729): setState() STATE_LISTEN -> STATE_LISTEN
I/BluetoothChat( 1729): MESSAGE_STATE_CHANGE: STATE_LISTEN
V/BluetoothEventRedirector( 1080): Received android.bleutooth.device.action.UUID
I/NotificationService( 1018): enqueueToast pkg=com.example.android.BluetoothChat callback=android.app.ITransientNotification$Stub$Proxy#446327c8 duration=0
I/BluetoothChat( 1729): MESSAGE_STATE_CHANGE: STATE_LISTEN
E/BluetoothEventLoop.cpp( 1018): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/1498/hci0/dev_00_06_66_03_0C_51
V/BluetoothEventRedirector( 1080): Received android.bleutooth.device.action.UUID
The device I'm trying to connect to is the 00:06:66:03:0C:51 which I can scan for and apparently pair with just fine.
The below is merged from a similar question which was successfully resolved by the selected answer here:
How can one connect to an rfcomm device other than another phone in Android?
The Android API provides examples of using listenUsingRfcommWithServiceRecord() to set up a socket and createRfcommSocketToServiceRecord() to connect to that socket.
I'm trying to connect to an embedded device with a BlueSMiRF Gold chip. My working Python code (using the PyBluez library), which I'd like to port to Android, is as follows:
sock = bluetooth.BluetoothSocket(proto=bluetooth.RFCOMM)
sock.connect((device_addr, 1))
return sock.makefile()
...so the service to connect to is simply defined as channel 1, without any SDP lookup.
As the only documented mechanism I see in the Android API does SDP lookup of a UUID, I'm slightly at a loss. Using "sdptool browse" from my Linux host comes up empty, so I surmise that the chip in question simply lacks SDP support.
Ok the short answer is I had to use this UUID in order to connect to my SPP device:
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
I tried to change it since I thought that only the "1101" part was important since I see that mentioned with SPP stuff all over the place on the intertubes but that made it not connect again. Apparently that specific UUID is what is supposed to be used to connect to generic SPP devices. Anyway just figured I'd post it up here so anyone who this sort of problem has an answer. Took me about 3 days to find it LOL!
I guess it is related to a sony-ericsson phones bug (see here).
I was able to connect from/to an android 2.0 device and my mac using bluetooth and a totally made-up UUID. Trying to make the same thing with a j2me device (a sony ericsson w910i) was working only if the android was the server, otherwise I get the same exception as you.
The UUID you are using, as far as I know, is a "base address" for the spp profile, and in the ServiceClassIDList field of the ServiceRecord returned by the server device when issuing a service discovery, it should be listed AFTER the UUID you decided to use..apparentely this is not the case in some situations (e.g. my phone first listed the generic UUID and then my custom UUID).
Looks like it's the same situation here.
You can try to manually change the ServiceRecord and return the proper ServiceClassIDList. Maybe it will work for you..unfortunately, my stupid cell phone refuse to change it :(
PS. a strange thing is that my mac is indeed able to see the service, even if the ServiceRecord is "broken", I guess that android just bother to see the first UUID in the ServiceClassIDList, while my pc go through the list searching every element. But this is just my supposition :)
The baud rate you set must match the device it's hooked to. They have the default 115200 or switch to 9600 but if you need other (1200 in my case for a survey instrument) you need to set that up through hyperterminal* and a null modem cable.
*Though the docs for the bluesnap device suggest using hyperterminal there are issues with it. After a few calls to bluesnap, they suggested:
First, when connecting the device to a PC, try putting the Jumper settings back to their original positions using 115200 8, N, 1 and X off. When DTE enabled, a terminal connection cannot be established without using special software specifically designed for DTR/DTE connections.
Second, HyperTerminal has known issues with the BlueSnap. I would recommend trying TeraTerm or PuTTY.
took me 4 days to find this out!
What baud rate do you have your bluetooth device set at? I'm connected, but my data is showing up as the typical garbled mush you get with mixed baud rates. I have mine set to 57600, this is what I've seen other folks use. Oh, thanks for posting your results the UUID had me working for a few days as well.
If 'sdptool browse' reports no information about the device try 'sdptool records [device-mac-here]'

Categories

Resources