I am working on an android application to hook up raspberry pi's to a local wifi network sending them ssid and ssid password information over bluetooth from my android phone. The rpi's are running node servers using bleno.
The set up of my application is as follows.
- I scan for ble devices displaying a checklist of devices for the user to select
- Once selected the user click button 'next' opening a new activity binding to a new
BluetoothLeService
. - This activity has a confirm button that when clicked starts the connection process of the ble peripheral to the phone.
- Once done sending ssid and ssid_pwd data to the peripheral I tear down and unbind from
BluetoothLeService
, finish that activity, and then start a success screen activity that routes the user back to the scanning screen to start that process all over again.
So that part is all fine. I can even select multiple peripherals to send data two and that works.
My problem comes after step 4. If a user decides to select another peripheral after they have already done one onServiceConnected
is called called for the new peripheral but mBluetoothGatt.discoverServices()
seems to pick up two services. Once for the previously connected peripheral and once for the new one.
Note: this only happens when I unbind from the service and then bind again later. Binding once and working with two peripherals seems to work.
What could be causing this? I have checked well over a dozen times that BluetoothLeService
is being destroyed, the activity that binding to BluetoothLeService
is being destroyed, even checking that the first peripheral isn't broadcasting or accepting ble connections. I have even physically unplugged the first rpi. The btsnoop_hci.log
shows connecting to one peripheral and then the other so it has to be within the app code. Does anyone have any ideas?
This is the part of the code that starts the mess.
private final BluetoothGattCallback mGattCallback =
new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction,gatt);
Log.i(TAG, "Connected to GATT server.");
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices()); // <-- The problem starts here
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction,gatt);
}
}
@Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
Log.w(TAG, "onServicesDiscovered received: " + status);
} else {
Log.e("ERROR", "Gatt onServiceDiscovered failed. Error code + " + status);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
Log.d("DEBUG", characteristic.getValue().toString());
}
@Override
// Result of a characteristic read operation
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
Log.d("DEBUG", characteristic.getValue().toString());
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
Log.d("DEBUG", characteristic.getValue().toString());
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
};
Thanks