Use Case: I wrote a security app, which runs alongside a bluetooth Mesh. The mesh contains custom lights and alarms. To check the status of the mesh system, my app scans one of the nearest devices (by RSSI strength) to see what data the bluetooth light/alarm contains in it's scan response packet. Because this is a security app, my app scans every 15 seconds to ensure it has the latest info at all times. Security threats are reported to the police, so it is important to be as up to date as possible. Seconds matter. After a couple of weeks or so of the app running, the app is able to scan the data, but can no longer connect to a device. The only way to "clear" an alarm is by using the app, so it is necessary to be able to write to a device when needed.
My Question: Why does this happen? How is it possible that I can scan devices, but no longer write to a device?
Affected Device Logcat: I was able to locate a device that was in this problem-state and collected the logcat while trying to write to a device. As you can see, I am able to connect, see the services, and even update the MTU. But cannot write to the device. My app automatically tries 5 attempts, and this is the last attempt. Please note that I tried toggling bluetooth on and off. Restarting the tablet did seem to fix the issue. Unfortunately, I didn't try closing and restarting the app first....
E/Bluetooth LE: Best RSSI Position set
E/Bluetooth LE: Bluetooth Device saved
D/BluetoothGatt: connect() - device: 00:A0:50:E1:88:51, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=3b720df8-2e40-47bf-aa2c-99c0c1fba362
E/Bluetooth LE: Attempting To Connect to GATT
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=00:A0:50:E1:88:51
D/BluetoothGatt: discoverServices() - device: 00:A0:50:E1:88:51
D/BluetoothGatt: onConnectionUpdated() - Device=00:A0:50:E1:88:51 interval=6 latency=0 timeout=500 status=0
D/BluetoothGatt: onSearchComplete() = Device=00:A0:50:E1:88:51 Status=0
E/Bluetooth: GATT Services count: 3
E/Bluetooth: Service Found - UUID: 00001800-0000-1000-8000-00805f9b34fb
E/Bluetooth: Service Found - UUID: 00001801-0000-1000-8000-00805f9b34fb
E/Bluetooth: Service Found - UUID: 0000cbbb-0000-1000-8000-00805f9b34fb
D/BluetoothGatt: configureMTU() - device: 00:A0:50:E1:88:51 mtu: 50
D/BluetoothGatt: onConnectionUpdated() - Device=00:A0:50:E1:88:51 interval=39 latency=0 timeout=500 status=0
D/BluetoothGatt: onConfigureMTU() - Device=00:A0:50:E1:88:51 mtu=50 status=0
D/Surface: Surface::disconnect(this=0x74241f7000,api=1)
D/View: [Warning] assignParent to null: this = android.widget.LinearLayout{f04b3f V.E...... ......ID 0,0-333,75}
D/BluetoothManager: getConnectedDevices
D/BluetoothManager: getConnectedDevices
E/Bluetooth Gatt: Closing Gatt
D/BluetoothGatt: cancelOpen() - device: 00:A0:50:E1:88:51
D/BluetoothGatt: close()
D/BluetoothGatt: unregisterApp() - mClientIf=6
D/BluetoothManager: getConnectedDevices
W/package.name: type=1400 audit(0.0:38806): avc: denied { search } for name="custom" dev="dm-0" ino=3890 scontext=u:r:untrusted_app:s0:c100,c256,c512,c768 tcontext=u:object_r:custom_file:s0 tclass=dir permissive=0
D/ViewRootImpl[Toast]: hardware acceleration = true , fakeHwAccelerated = false, sRendererDisabled = false, forceHwAccelerated = false, sSystemRendererDisabled = false
D/Surface: Surface::connect(this=0x74241f7000,api=1)
D/Surface: Surface::allocateBuffers(this=0x74241f7000)
D/BluetoothAdapter: isLeEnabled(): ON
D/BluetoothLeScanner: onScannerRegistered() - status=6 scannerId=-1 mScannerId=0
D/BluetoothAdapter: isLeEnabled(): ON
D/BluetoothLeScanner: could not find callback wrapper
Further Testing: To conduct some testing, I made a small app that can toggle a light on and off. I set the app to scan every 3 seconds for over an hour. The results were similar in that I could scan for devices, but not connect and toggle the light by writing data to it. After the issue occured in the new toggle-app, I swapped over to my main security app, which had been running the whole time, and it worked fine. Apparently, the issue only affects the app that is scanning too frequently. The difference in the logcat bothers me a bit though - after the problem occurred, the logcat shows the onClientRegistered status as 133, which makes some sense. The main app did not show that though. I wonder if these are two different issues?
D/BluetoothAdapter: STATE_ON
D/BluetoothAdapter: STATE_ON
D/BluetoothLeScanner: Start Scan with callback
D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=9 mScannerId=0
D/InputTransport: Input channel constructed: fd=88
D/ViewRootImpl#dc2b515[Toast]: setView = android.widget.LinearLayout{251b02a V.E...... ......I. 0,0-0,0} TM=true MM=false
V/Toast: Text: Uogg in android.widget.Toast$TN#af0fe1b
D/ViewRootImpl#dc2b515[Toast]: dispatchAttachedToWindow
D/ViewRootImpl#dc2b515[Toast]: Relayout returned: old=[0,63][1080,2094] new=[247,1810][832,1926] result=0x7 surface={valid=true 509882912768} changed=true
D/OpenGLRenderer: eglCreateWindowSurface = 0x76b4a19080, 0x76b763d010
D/BluetoothAdapter: STATE_ON
D/BluetoothGatt: connect() - device: 00:A0:50:DF:22:58, auto: false
D/BluetoothAdapter: isSecureModeEnabled
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=0241923a-48e6-426a-81c0-acbea6690766
D/BluetoothGatt: onClientRegistered() - status=133 clientIf=0
E/Bluetooth LE: Disconnected from GATT
E/Bluetooth Gatt: Closing Gatt
D/BluetoothGatt: cancelOpen() - device: 00:A0:50:DF:22:58
D/BluetoothGatt: close()
D/BluetoothGatt: unregisterApp() - mClientIf=0
Airplane Mode: For some reason, toggling bluetooth on and off did nothing, but turning on Airplane mode solved the onClientRegistered() - status 133 issue. I have no idea why this would be. Does Airplane mode clear all bluetooth cache or similar? Currently, my attempt was to toggle bluetooth off/on every 6 hours, but that doesn't seem to work. I'm not clearing the cache though.
Other than having the clients turn their devices off nightly, which I can't guarantee they do, nothing seems to resolve the issue. Any thoughts are welcome here.
Edit: I turned off my device's bluetooth and noticed that my logcat shows D/BluetoothAdapter: isLeEnabled(): ON when trying to toggle one of the Bluetooth lights. I also saw this appear in my affected device's logcat after trying to scan and connect to a device. I'm wondering if I need to toggle bluetooth and Bluetooth LE both off to refresh everything. Toggling bluetooth on and off does nothing helpful at this point. I am using a BluetoothLE scanner, so it would make some sense. A little odd toggling bluetooth doesn't affect LE. Searching google shows the below (Full Code/Credit Here):
#SystemApi
public boolean isLeEnabled() {
final int state = getLeState();
if (DBG) {
Log.d(TAG, "isLeEnabled(): " + BluetoothAdapter.nameForState(state));
}
return (state == BluetoothAdapter.STATE_ON
|| state == BluetoothAdapter.STATE_BLE_ON
|| state == BluetoothAdapter.STATE_TURNING_ON
|| state == BluetoothAdapter.STATE_TURNING_OFF);
}
I think that you can use this code:
Future<void> scanPrinters() async {
// CHECK TO PUT INIT
flutterBlue.startScan(timeout: Duration(seconds: 4));
flutterBlue.scanResults.listen((results) {
for (blueB.ScanResult r in results) {
print('Device ${r.device.name} found!');
}
});
printerManager.startScan(Duration(seconds: 3));
printerManager.scanResults.listen((results) {
print("dipositi" + results.toString());
setState(() {
printers = results;
});
});
}
Related
In my app I have tried everything to connec my BLE device and receive calls to onCharacteristicChanged. I have had success with initial connection where my console reads like this:
BluetoothGatt: onConnectionUpdated() - Device=B4:E6:2D:B3:D0:DB interval=6 latency=0 timeout=500 status=0
BluetoothGatt: setCharacteristicNotification() - uuid: 0a990c1f-0000-441c-8f7d-f775b6ff9400 enable: true
BluetoothGatt: setCharacteristicNotification() - uuid: f7c21d1c-0000-4b9b-ab7e-e1d8e7a51724 enable: true
Although I have no calls to onCharacteristicChanged?
I am not sure this is the proper way to check but I have used nRF Connect app to test if there is any activity between the BLE device and the Android phone. Using that app, it recoded no activity after connecting to the device. Just to be sure, I tested other BLE devices and saw the expected activity.
The BLE device has 8 characteristics that I read/get notified from, and another 8 that I write to (16 total). I have read that Android may only support 15, I could be wrong on how this works.
Does any of this seem like an issue? I can post code too.
I am developing an Android App that communicates with a BLE Peripheral. I am able to enable the notifications and receive data from the BLE Peripheral. However, a few seconds later, I receive the following message on my Android Terminal in Android Studio and the Notifications stop.
I noticed that Android phone is still connected to the BLE Peripheral as Status = 0, but after the BLE Connection Interval Change = 156, the Notifications stop.
Has anyone encountered a similar problem? I am using the BluetoothLEGatt example from Android Studio.
Thanks
Hani Abidi
D/BluetoothGatt: onClientConnParamsChanged() - Device=80:EA:CA:00:A8:77 interval=156 status=0enter code here
So I ran into this issue as well and although I don't 100% know the exact cause, I can at least relay how I "fixed" the problem and my experiences.
So I'm using a Samsung Galaxy Note 4 running 6.0.1 and using RxAndroidBle to ease the pain of having to deal with BLE on Android. My application connects to a PSoC4 BLE microprocessor and immediately does a back and forth data transfer with said microprocessor. What I was seeing was similar to the OP: more often than not the back and forth transmission would just stop dead in its tracks with the following messages:
03-15 16:06:39.989 27793-28784/application D/BluetoothGatt: onClientConnParamsChanged() - Device=00:A0:50:65:24:91 interval=6 status=0
03-15 16:06:40.289 6292-6754/? D/BtGatt.GattService: onClientConnParamsChanged() - clientIf=7 address=00:A0:50:65:24:91, interval=39status=0
03-15 16:06:40.289 27793-28561/application D/BluetoothGatt: onClientConnParamsChanged() - Device=00:A0:50:65:24:91 interval=39 status=0
03-15 16:06:54.989 6292-6754/? D/BtGatt.GattService: onClientConnParamsChanged() - clientIf=7 address=00:A0:50:65:24:91, interval=6status=0
03-15 16:06:54.989 27793-27823/application D/BluetoothGatt: onClientConnParamsChanged() - Device=00:A0:50:65:24:91 interval=6 status=0
03-15 16:06:55.259 6292-6754/? D/BtGatt.GattService: onClientConnParamsChanged() - clientIf=7 address=00:A0:50:65:24:91, interval=39status=0
03-15 16:06:55.259 27793-28784/application D/BluetoothGatt: onClientConnParamsChanged() - Device=00:A0:50:65:24:91 interval=39 status=0
It appeared to me at first that for some reason the phone was still negotiating the connection interval in the middle of the data transfer and, for some reason, would just completely get screwed up as a result.
Maybe this is what is happening, maybe it isn't, but what I found was the root cause of this was that I am (apparently) connecting and interfacing with my microprocessor over BLE before the BLE device scanner is completely done shutting down.
When the user taps on the table view cell to connect to the device, I was originally calling to stop subscribing to the RxAndroidBle observable that is scanning for devices, which should end the BLE scanning and then immediately launched into showing a new Activity for communicating with the PSoC4 which in turn immediately connects and starts interfacing with the microprocessor:
scanSubscription.unsubscribe();
Intent myIntent = new Intent(MainActivity.this, ConnectedActivity.class);
myIntent.putExtra("address", testdevice.getAddress());
myIntent.putExtra("name", testdevice.getName());
MainActivity.this.startActivityForResult(myIntent, CONNECTED_ACTIVITY);
It appears, however, that simply unsubscribing from the scan subscription does not immediately end the BLE scanning so my current strategy is to wait 500 ms before starting any communications with the other device. This is obviously not ideal - ideally you'd have a method callback when scanning actually was ceased, but I haven't figured out how to do that just yet.
Hopefully this helps someone.
Connection parameter update is unrelated to notification subscription status. Are you saying your onCharacteristicChanged are not being called although you send notifications from the peripheral? You should check your code again. If you think you've done everything correct you should check android's hci snoop log or use a BLE sniffer to see what really happens.
Here is the list of error which i got while developing BLE App for A&D UA-651BLE model
onClientConnectionState() - status=8 clientIf=5 device=D0:5F:B8:03:79:70
onClientConnectionState() - status=22 clientIf=5 device=5C:31:3E:5E:E2:36
onClientConnectionState() - status=19 clientIf=5 device=5C:31:3E:5E:E2:36
As of now I'm handling this with gatt.disconnect(); ,
Description of above error codes :
22 is 0x16 which means connection terminated by local host.
8 is 0x8 which means connection timeout.
19 is 0x13 which means connection terminate by peer user.
How to handle this in different way?
1.Is there any way to handle this issue other than disconnecting BluetoothGatt? (Just curious to know)
2.Shall I show popup to user that your values are stored in BP device,On next successful connection vital device will push your values automatically?
P.S: If I see from developer's perspective,I know that this is BLE Stack exception,By if i see from user's perspective,they will think something wrong in android app,that is why it is not Showing my BP reading in android Screen.
I am developing an application using the RxAndroidBle library that performs BLE scans regularly about every 30 seconds, and some BLE operations every minute or so. After a couple of hours, usually between 5 and 24h, the scan stops working. Every time a scan is supposed to be started, I get:
09-05 09:08:37.160 8160-8160/myapp D/BluetoothAdapter: startLeScan(): null
09-05 09:08:37.165 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.165 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.165 8160-8160/myapp D/BluetoothLeScanner: Start Scan
09-05 09:08:37.165 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.165 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.170 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.170 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:37.210 8160-12850/myapp D/BluetoothLeScanner: onClientRegistered() - status=133 clientIf=0
09-05 09:08:37.210 8160-12850/myapp D/BluetoothLeScanner: Registration failed, unregister clientIf = 0
09-05 09:08:37.215 8160-8160/myapp D/BluetoothLeScanner: Scan failed, reason app registration failed for UUID = 4c321920-a2b7-449a-bc24-ea4361f7a255
09-05 09:08:44.150 8160-8160/myapp V/myapp.debug: unsubscribing scan
09-05 09:08:44.150 8160-8160/myapp V/myapp.debug: Clearing scan subscription
09-05 09:08:44.150 8160-8160/myapp D/BluetoothAdapter: stopLeScan()
09-05 09:08:44.150 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:44.155 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:44.155 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:44.155 8160-8160/myapp D/BluetoothAdapter: STATE_ON
09-05 09:08:44.155 8160-8160/myapp D/BluetoothLeScanner: could not find callback wrapper
Does anyone have any idea of what causes this problem or what can be done to fix it?
On the older implementations of Android there seems to be a race condition between the time a bluetooth adapter is enabled and how quickly you can do a scan. You can trigger this error by either trying to scan with a disabled bluetooth adapter or one that is transitioning (or has open connections and is trying to read). The underlying issue that was causing it in my app was the inability of the bluetooth sub system to get a new bluetooth socket. The answer above (running out of GATT resources) could be part of it. The overall logic in an older Android device to avoid this issue is: 1. Make sure you disable/enable the bluetooth adapter about every 5 scans. This seems to help clear out older cached data. 2. Make sure you don't try to initiate a scan while the bluetooth adapter is not enabled (this is made possible if you are disabling/enabling on a regular basis). 3. Make sure you have a delay between disconnecting from GATT interfaces and doing your next scan. 4. Don't try to read the GATT characteristics of any more than about 3 devices at a time.
Overall, its somewhat unavoidable in an older Android device to completely avoid the problem but you can mitigate it by carefully timing your scan/stop scan/connect/disconnect/ cycle.
The problem is that after couple of connections you reach a maximal number of BluetoothGatt objects.
After you disconnect every device before you start a new scan call close() on your BluetoothGatt object.
I am using th kontakt sdk along with radius beacon.
Here is the activity code:
http://pastebin.com/TQXdKwkX
But it isn't able to detect the beacon, what I see in logs is:
D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
How can this be possibly fixed ?
Thanks