Android App receives 2 connections from the same device (nRF Module)

104 views Asked by At

I have an android app which scans and connects to a predefined device name. My peripheral is an nRF module which is sending an incrementing data at 1Hz. However, when I launch the app, it scans and logs multiple connections to the same device and consequently the values received duplicated values. So if there is a log for 3 connections then I get 3 duplicate values and 2 duplicates if there are 2 connections.

D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=14 device=FD:72:38:AA:1A:E7
I/BLE log: Connected to device FD:72:38:AA:1A:E7
D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=15 device=FD:72:38:AA:1A:E7
I/BLE log: Connected to device FD:72:38:AA:1A:E7

Here is my code:

Scanning:

private fun bleScan() {
        val scanFilter = ScanFilter.Builder()
            .setDeviceName("VEGA-TEST")
            .build()

        val scanSettings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .build()

        bleScanner.startScan(mutableListOf(scanFilter), scanSettings, object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult) {
                super.onScanResult(callbackType, result)
                with(result.device) {
                    Log.i("BLE log", "Found device $address")
                    connectGatt(this@BluetoothService, false ,gattCallback)
                }
            }
        })
    }

GATT Connections

private val gattCallback = object : BluetoothGattCallback() {
        override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
            super.onConnectionStateChange(gatt, status, newState)

            val deviceAddr = gatt.device.address

            if(status == BluetoothGatt.GATT_SUCCESS) {
                when(newState) {
                    BluetoothProfile.STATE_CONNECTED -> {
                        Log.i("BLE log", "Connected to device $deviceAddr")
                        bleStopScan()
                        Handler(Looper.getMainLooper()).post {
                            gatt.discoverServices()
                        }
                    }
                    BluetoothProfile.STATE_DISCONNECTED -> {
                        Log.i("BLE log", "Disconnected from device $deviceAddr")
                    }
                    else -> {
                        Log.i("BLE log", "Hit event $newState")
                    }
                }
            } else {
                Log.e("BLE log", "BLE error $status for $deviceAddr")
            }

        }

        override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
            super.onServicesDiscovered(gatt, status)
            with(gatt) {
                Log.i("BLE log","Discovered ${services.size} services for ${device.address}")
                printGattTable()
                enableNotification(gatt)
            }
        }
    }

On the NRF Side i am sending data using a timer

static void txTimer_hander(void *p_context){
    //TODO: Handle timeout
    // SEND data to Device
    //NRF_LOG_INFO("Timer : %d", tx_Data);
    memset(val, 0, 7);
    if(tx_Data < 50){
        // SEND this Data
        uint16_t now_data = tx_Data;
        val[0] = 0xFF;
        val[5] = now_data;
        //memcpy(&val[0], (uint16_t*)0xFF, 1);
        //memcpy(&val[6], &now_data, 2);
        //val[0] = now_data;
        //
        
        tx_Data++;
    }else{
        tx_Data = 0;
        // SEND this Data
        uint16_t now_data = tx_Data;
        //memcpy(&val[0], (uint16_t*)0xFF, 1);
        val[0] = 0xFF;
        val[5] = now_data;
        //memcpy(&val[6], &now_data, 2);
        //
        tx_Data++;
    }
    NRF_LOG_INFO("Sending %d", tx_Data);
    send_nus_data(val, 7);
}

NOTE I am using Android 12 and testing using Android Studio

I would appreciate any help! Thanks

1

There are 1 answers

0
Emil On

If your phone catches two advertisement packets, it will create two logical connections. You should check before you call connectGatt if you have already called connectGatt, and if so don't connect again. You should also stop the scan if you don't need the scan to continue when you have already found a device.