Most of the time the connection does not work
I've been trying to find a solution for this error for two days now and I can't understand what happens to the connection not working. I have to try many, many times until the connection works.
Device: Samsung A13 Android version: 12
Log from logcat:
04 12:27:54.427 18420 18551 D BluetoothGatt: connect() - device: FE:EB:A9:02:1B:78, auto: false
12-04 12:27:54.427 18420 18551 I BluetoothAdapter: isSecureModeEnabled
12-04 12:27:54.428 1573 3519 D BtConfig.SecureMode: isSecureModeOn:false
12-04 12:27:54.428 18420 18551 D BluetoothGatt: registerApp()
12-04 12:27:54.429 18420 18551 D BluetoothGatt: registerApp() - UUID=31e09b9f-c264-41ea-bdd8-b17c8a835759
12-04 12:27:54.431 1573 3519 D BtGatt.GattService: registerClient(com.cleanproject) - UUID=31e09b9f-c264-41ea-bdd8-b17c8a835759
12-04 12:27:54.433 1573 3519 D BtGatt.ContextMap: add() - appUid: 10303, appPid: 18420, appName: com.cleanproject
12-04 12:27:54.435 1573 1672 D BtGatt.GattService: onClientRegistered() - UUID=31e09b9f-c264-41ea-bdd8-b17c8a835759, clientIf=9
12-04 12:27:54.436 18420 18808 D BluetoothGatt: onClientRegistered() - status=0 clientIf=9
12-04 12:27:54.443 1573 3519 D BtGatt.GattService: clientConnect(com.cleanproject) - address = FEEBA9_8, isDirect=true transport =2 set own addr = false own addr type:0, clientIf: 9, opportunistic=false, phy: 7
12-04 12:27:54.444 1573 2347 W bt_btm : BTM_SecAddBleDevice: dev_type=0x2
12-04 12:27:54.444 1573 2347 E bt_stack: [ERROR:gatt_api.cc(1237)] GATT_Connectgatt_if=9, address=fe:eb:a9:02:1b:78, is_direct=1, opportunistic=0
12-04 12:27:54.445 1573 2347 I bt_stack: [INFO:gatt_attr.cc(888)] gatt_sr_init_cl_status: bda=fe:eb:a9:02:1b:78, cl_supp_feat=0000, aware=1
12-04 12:27:54.445 1573 2347 W bt_btm : btm_ble_disable_resolving_list() rl_state = 0x0, rl_mask = 0x1, to_resume = 1
12-04 12:27:54.580 1129 1129 I GestureDetector: handleMessage TAP
12-04 12:27:54.580 1129 1154 I GestureDetector: handleMessage TAP
12-04 12:27:54.902 760 798 D BatteryDump: wait_for_battery_event : occurred : change@/devices/platform/samsung_mobile_device/samsung_mobile_device:battery/power_supply/battery
12-04 12:27:54.906 760 760 I [email protected]: updateLrpSysfs: write: 292
12-04 12:27:54.954 820 820 I SurfaceFlinger: SFWD update time=54861089575760
12-04 12:27:55.214 1129 1479 D NetdEventListenerService: DNS Requested by : 100, 10303, 0
12-04 12:27:55.810 368 368 D io_stats: !@ 179,0 r 509958 15388139 w 192676 6511972 d 41720 6263184 f 0 0 iot 252256 0 th 0 0 0 pt 0 inp 0 0 54861.945
12-04 12:27:57.104 1129 2164 D SamsungAlarmManager: Cancel Alarm calling from uid:10179 pid :15801 / OP:PendingIntent{866a8f5: PendingIntentRecord{2fd805e com.google.android.gms/ startService}}
12-04 12:27:57.106 1129 2164 V SamsungAlarmManager: setLocked to kernel - W:54947402 / NW:54866135, now=54863241
12-04 12:27:57.110 1129 2164 D SamsungAlarmManager: Cancel Alarm calling from uid:10179 pid :2269 / OP:PendingIntent{daec68a: PendingIntentRecord{48a490c com.google.android.gms/ startService}}
12-04 12:27:57.111 1129 2164 V SamsungAlarmManager: setLocked to kernel - W:54947402 / NW:54866135, now=54863246
12-04 12:27:57.242 1129 1479 D NetdEventListenerService: DNS Requested by : 100, 10303, 0
12-04 12:27:57.281 1129 1183 D PowerManagerService: UserActivityStateListenerState: 0
12-04 12:27:57.514 1506 1506 I wpa_supplicant: Heartbeat 5468
12-04 12:27:59.260 1129 1479 D NetdEventListenerService: DNS Requested by : 100, 10303, 0
12-04 12:27:59.446 1573 2347 I bt_stack: [INFO:gatt_attr.cc(342)] gatt_connect_cback: remove untrusted client status, bda=fe:eb:a9:02:1b:78
12-04 12:27:59.447 1573 2347 W bt_stack: [WARNING:bta_gattc_act.cc(384)] bta_gattc_open_fail: Cannot establish Connection. conn_id=000000. Return GATT_ERROR(133)
12-04 12:27:59.454 1573 2347 W bt_btm : btm_ble_disable_resolving_list() rl_state = 0x0, rl_mask = 0x1, to_resume = 1
12-04 12:27:59.455 1573 1672 D BtGatt.GattService: onConnected() - clientIf=9, connId=0, status=133, address=FEEBA9_8
12-04 12:27:59.456 18420 18808 D BluetoothGatt: onClientConnectionState() - status=133 clientIf=9 device=FE:EB:A9:02:1B:78
12-04 12:27:59.463 18420 18420 D ReactNativeBleManager: onConnectionStateChange to 0 on peripheral: FE:EB:A9:02:1B:78 with status 133
12-04 12:27:59.464 18420 18420 D BluetoothGatt: close()
12-04 12:27:59.473 18420 18420 D BluetoothGatt: unregisterApp() - mClientIf=9
12-04 12:27:59.476 1573 3519 D BtGatt.GattService: unregisterClient(com.cleanproject) - clientIf=9
12-04 12:27:59.478 1573 3519 D BtGatt.ContextMap: remove() - id: 9
12-04 12:27:59.478 1573 3519 E BtGatt.ContextMap: remove() - removed: 9
12-04 12:27:59.479 1573 2347 I bt_stack: [INFO:gatt_api.cc(1102)] GATT_Deregister gatt_if=9
12-04 12:27:59.479 1573 2347 I bt_stack: [INFO:gatt_api.cc(1155)] Initialize tGATT_REG
12-04 12:27:59.480 18420 18420 D BluetoothGatt: cancelOpen() - device: FE:EB:A9:02:1B:78
12-04 12:27:59.480 18420 18420 D BluetoothGatt: close()
12-04 12:27:59.482 18420 18550 I ReactNativeJS: 'Connection error', 'Connection error'
12-04 12:27:59.485 18420 18420 D BluetoothGatt: unregisterApp() - mClientIf=0
12-04 12:27:59.488 18420 18420 D ReactNativeBleManager: Peripheral event (BleManagerDisconnectPeripheral):FE:EB:A9:02:1B:78
12-04 12:27:59.488 18420 18420 D ReactNativeBleManager: Disconnect
12-04 12:27:59.489 18420 18550 I ReactNativeJS: Ok
12-04 12:27:59.555 18420 18550 I ReactNativeJS: Disconnected from FE:EB:A9:02:1B:78
12-04 12:28:00.000 1129 1250 D SamsungAlarmManager: Expired : 8
Could you paste here the code relevant to how you connect to the device? What error do you get? Does it work on other devices? Can you connect to your device using nRF Connect app from Google Play?
Yes.
On build.gradle:
implementation 'no.nordicsemi.android.support.v18:scanner:1.6.0'
implementation 'no.nordicsemi.android:ble:2.6.0-alpha04'
On DanScanManager.java:
@Override
public void scan(ReadableArray serviceUUIDs, final int scanSeconds, ReadableMap options, Callback callback) {
// Scanning settings
final ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setReportDelay(0)
.setUseHardwareBatchingIfSupported(false)
.build();
final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
scanner.startScan(null, settings, mScanCallback);
if (scanSeconds > 0) {
Thread thread = new Thread() {
private int currentScanSession = scanSessionId.incrementAndGet();
@Override
public void run() {
try {
Thread.sleep(scanSeconds * 1000);
} catch (InterruptedException ignored) {
}
runOnUiThread(new Runnable() {
@Override
public void run() {
BluetoothAdapter btAdapter = getBluetoothAdapter();
// check current scan session was not stopped
if (scanSessionId.intValue() == currentScanSession) {
if(btAdapter.getState() == BluetoothAdapter.STATE_ON) {
scanner.stopScan(mScanCallback);
}
WritableMap map = Arguments.createMap();
bleManager.sendEvent("BleManagerStopScan", map);
}
}
});
}
};
thread.start();
}
callback.invoke();
}
private ScanCallback mScanCallback = new ScanCallback() {
public void onScanResult(final int callbackType, @NonNull final ScanResult result) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.i(bleManager.LOG_TAG, "DiscoverPeripheral: " + result.getDevice().getName());
DanPeripheral peripheral = (DanPeripheral) bleManager.getPeripheral(result.getDevice());
if (peripheral == null) {
peripheral = new DanPeripheral(bleManager.getReactContext(), result);
} else {
peripheral.updateData(result);
peripheral.updateRssi(result.getRssi());
}
bleManager.savePeripheral(peripheral);
WritableMap map = peripheral.asWritableMap();
bleManager.sendEvent("BleManagerDiscoverPeripheral", map);
}
});
}
public void onBatchScanResults(@NonNull final List<no.nordicsemi.android.support.v18.scanner.ScanResult> results) {
}
@Override
public void onScanFailed(final int errorCode) {
WritableMap map = Arguments.createMap();
bleManager.sendEvent("BleManagerStopScan", map);
}
};
On Peripheral.java:
public void connect(Callback callback, Activity activity) {
if (!connected) {
BluetoothDevice device = getDevice();
this.connectCallback = callback;
this.connecting = true;
Handler handler = new Handler(Looper.getMainLooper());
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
Log.d(BleManager.LOG_TAG, "connectGatt(activity, false, this, BluetoothDevice.TRANSPORT_LE, PhyRequest.PHY_LE_1M_MASK | PhyRequest.PHY_LE_2M_MASK | PhyRequest.PHY_LE_CODED_MASK, handler)");
gatt = device.connectGatt(activity, false, this,
BluetoothDevice.TRANSPORT_LE, 1 | 1 << 1 | 1 << 2, handler);
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
// A variant of connectGatt with Handled can't be used here.
// Check https://github.com/NordicSemiconductor/Android-BLE-Library/issues/54
// This bug specifically occurs in SDK 26 and is fixed in SDK 27
Log.d(BleManager.LOG_TAG, "connectGatt(activity, false, this, BluetoothDevice.TRANSPORT_LE, PhyRequest.PHY_LE_1M_MASK | PhyRequest.PHY_LE_2M_MASK | PhyRequest.PHY_LE_CODED_MASK)");
gatt = device.connectGatt(activity, false, this,
BluetoothDevice.TRANSPORT_LE, 1 | 1 << 1 | 1 << 2/*, handler*/);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Log.d(BleManager.LOG_TAG, "connectGatt(activity, false, this, BluetoothDevice.TRANSPORT_LE)");
gatt = device.connectGatt(activity, false, this,
BluetoothDevice.TRANSPORT_LE);
} else {
Log.d(BleManager.LOG_TAG, "connectGatt(activity, false, this)");
gatt = device.connectGatt(activity, false, this);
}
} else {
if (gatt != null) {
callback.invoke();
} else {
callback.invoke("BluetoothGatt is null");
}
}
}
I see you're not using the BLE library, just the native API directly with some code copied from here. Is it because it didn't work for you?
Did you try connecting with just PHY_LE_1M_MASK, not all 3?
Sorry...
Follow the code using Android-BLE-Library.
Peripheral.java:
...
public class Peripheral extends BluetoothGattCallback {
...
public Peripheral(BluetoothDevice device, int advertisingRSSI, byte[] scanRecord, ReactContext reactContext) {
this.device = device;
this.bufferedCharacteristics = new HashMap<String, NotifyBufferContainer>();
this.advertisingRSSI = advertisingRSSI;
this.advertisingDataBytes = scanRecord;
this.danBleManager = new DanBleManager(reactContext);
this.reactContext = reactContext;
}
...
public void connect(Callback callback, Activity activity) {
if (!connected) {
BluetoothDevice device = getDevice();
this.connectCallback = callback;
this.connecting = true;
/* called when the request is about to be executed */
this.danBleManager.connect(this.device)
// Automatic retries are supported, in case of 133 error.
.retry(3 /* times, with */, 100 /* ms interval */)
// A connection timeout can be set. This is additional to the Android's connection timeout which is 30 seconds.
.timeout(15_000 /* ms */)
// The auto connect feature from connectGatt is available as well
.useAutoConnect(true)
// This API can be set on any Android version, but will only be used on devices running Android 8+ with
// support to the selected PHY.
.usePreferredPhy(PhyRequest.PHY_LE_1M_MASK | PhyRequest.PHY_LE_2M_MASK | PhyRequest.PHY_LE_CODED_MASK)
// A connection timeout can be also set. This is additional to the Android's connection timeout which is 30 seconds.
.timeout(15_000 /* ms */)
.then(result -> { Log.d(BleManager.LOG_TAG, "Finished connect to device: " + this.device.getAddress());sendConnectionEvent(device, "BleManagerConnectPeripheral", BluetoothGatt.GATT_SUCCESS);Callback.invoke(); /* called when the request was finished with either success, or a failure */ })
.fail(new FailCallback() {
@Override
public void onRequestFailed(@NonNull BluetoothDevice device, int status) {
Log.d(BleManager.LOG_TAG, "Failed to connect to: " + device.getAddress() + " with status " + status);
sendConnectionEvent(device, "BleManagerDisconnectPeripheral", BluetoothGatt.GATT_FAILURE);
callback.invoke("Connection error.");
}
})
// Each request must be enqueued.
// Kotlin projects can use suspend() or suspendForResult() instead.
// Java projects can also use await() which is blocking.
.enqueue();
} else {
if (connected) {
callback.invoke();
} else {
callback.invoke("BluetoothGatt is null");
}
}
}
...
}
From the log you posted in the first message it looks like you're getting error 133. This is a generic error, which doesn't say much.
What you may try:
- Check without
.usePreferredPhy(PhyRequest.PHY_LE_1M_MASK | PhyRequest.PHY_LE_2M_MASK | PhyRequest.PHY_LE_CODED_MASK)
- Check if you can connect to that device using nRF Connect app.
- Try connecting to your device from another phone.
- As this is not really an issue with the BLE library, but either with the phone or your device, try asking this question on DevZone, where you can also get help regarding the fw. They may ask you to get sniffer logs, etc.
Hi, I have a question in a similar setup. So we use the blinky example, but modified values of the service uuid and chars to connect to a Nordic NUS peripheral. The blinky calls into this Android-BLE-Library. I've tracked the logcat output, it's making call using only 1M for phy, like:
gatt = device.connectGatt(context, false, callback,
BluetoothDevice.TRANSPORT_LE, PhyRequest.PHY_LE_1M_MASK, handler);
The question is, in the output of HCI snoop log, it enables both the 2M and Coded phy:
Command Opcode: LE Extended Create Connection (0x2043)
......
Initiating PHYs: 0x7, LE Coded, LE 2M, LE 1M
0000 0... = Reserved: 0x00
.... .1.. = LE Coded: True
.... ..1. = LE 2M: True
.... ...1 = LE 1M: True
Is this normal or a bug somewhere in the Android library or stack? Is there a way to disable the 2M and Coded bits on this HCI command, where to change the code? I hope there is a way to fix it on the Android side, or at least we know better about it. At the same time, we are also looking into the peripheral side.
When using sniffer, I can see the LL_FEATURE_REQ are having coded-phy and 2M bits set. I'm assuming if we change the "LE Extended Create Connection" command parameter on HCI, it may fix the problem. The problem happens on multiple recent phones and tablets using Mediatek chipsets.
Any comments or hints will be appreciated.
Thanks.
From our experience Android completely ignores "preferred PHY" and knows better.