BLE service is not found by UUID (the UUID is correct in the code)


I had started this BLE project in Python, ran into problems with android permissions, so I had a go at (I'll be honest... vibe) coding a native Kotlin android app. The main part of it is to run a thread that will repeatedly poll a specific characteristic by id and send the data by UDP.

So far, it's finding and connecting to the device:

            val device = bluetoothAdapter.getRemoteDevice(targetDeviceAddress)
            bluetoothGatt = device.connectGatt(context, false, gattCallback)

That is triggering onConnectionStateChange(). I know this is happening because the Bluetooth device responds at this point.

This calls gatt.discoverServices(), which triggers onServicesDiscovered():

            override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    val service = gatt.getService(UUID.fromString(targetServiceUuid))
                    if (service != null) {
                        targetCharacteristic = service.getCharacteristic(UUID.fromString(targetCharacteristicUuid))
                        _status.value = BleStatus.Connected
                    } else {
                        _status.value = BleStatus.Error("Service not found")
                    }
                } else {
                    _status.value = BleStatus.Error("Service discovery failed")
                }
            }

I know it's entering this function because "Service not found" flashes in the app's status box. This is the only place where this string is found -- so it is definitely trying to get the service (based on targetServiceUuid, which I've verified by listing the device's services), and it isn't found.

That is -- as far as I know, I'm requesting a correct service UUID, but nothing is coming back, and I'm out of ideas.

The app is also requesting Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT and Manifest.permission.ACCESS_FINE_LOCATION permissions before this (and I checked the apps permissions in the settings -- it does have "location" and "nearby devices," so I believe the failure isn't due to insufficient permissions).

It's a OnePlus (Oppo) phone with Android 14. The device is a BBC Micro:bit.

What am I missing? Thanks.

FURTHER INFORMATION:

With some more logging, I found that the micro:bit's services are being reported differently on the computer compared to the phone.

Leaving out irrelevant results, a python+bleak script running on the computer reports that e95d0753-251d-470a-a062-fa1922dfa9a8 (Handle: 40): MicroBit Accelerometer Service exists.

But this UUID is absent from the Android environment.

Logging Kotlin code looks like this:

                    val uuid = UUID.fromString(targetServiceUuid)
                    val lsb = uuid.getLeastSignificantBits()
                    val msb = uuid.getMostSignificantBits()
                    Log.i("mb2o", "targetServiceUuid string = %s".format(targetServiceUuid))
                    Log.i("mb2o", "lsb hex = %s".format(lsb.toHexString()))
                    Log.i("mb2o", "msb hex = %s".format(msb.toHexString()))

                    // this is poorly factored but will delete later
                    val srvIter = gatt.getServices().iterator()
                    while (srvIter.hasNext()) {
                        var srvc = srvIter.next()
                        Log.i("mb2o", "service = %s".format(srvc.uuid))
                    }

and prints

targetServiceUuid string = e95d0753-251d-470a-a062-fa1922dfa9a8
lsb hex = a062fa1922dfa9a8
msb hex = e95d0753251d470a
service = 00001800-0000-1000-8000-00805f9b34fb
service = 00001801-0000-1000-8000-00805f9b34fb
service = 0000fe59-0000-1000-8000-00805f9b34fb
service = e97dd91d-251d-470a-a062-fa1922dfa9a8
service = 0000180a-0000-1000-8000-00805f9b34fb
service = e95d93af-251d-470a-a062-fa1922dfa9a8

e95d93af-251d-470a-a062-fa1922dfa9a8 is a near match but corresponds to the micro:bit event service, not the accelerometer.

A puzzling result. Well, maybe the event service will work for this.

0
Apr 3 at 1:52 PM
User Avatarjamshark70
#android#bluetooth-lowenergy

No answer found for this question yet.