How can I use semaphore to do a correct android ble communication?

544 views Asked by At

I have one doubt with ble communication from my Android app and one peripheral. This peripheral sends data through notify on a certain characteristics "A" and I can write on it on another certain characteristics "B". For do that I do in this way:

   Semaphore sem = new Semaphore(1);
   void notifyActivation()
    {bluetoothGatt.setCharacteristicNotification(characteristic, true);

    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
            UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
    if(descriptor != null )
    {

        try 
        {
            sem.acquire();
        } 
        catch (InterruptedException e) 
        {
            e.printStackTrace();
        }

        Log.i("debug","scrittura descrittore");
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        bluetoothGatt.writeDescriptor(descriptor);
    }
 }

@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) 
                {
                    super.onDescriptorWrite(gatt, descriptor, status);
                    Log.i("debug", "descriptor status: "+status);

                    sem.release();
                }


public void write(final BluetoothGattCharacteristic characteristic)
{

    new Thread(new Runnable() {

        @Override
        public void run() {

            try {
                //acquisisco il semaforo se รจ libero se no mi blocco
                sem.acquire();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    boolean res=bluetoothGatt.writeCharacteristic(characteristic);

    if(!res)
    {
        Log.i("debug","scrittura fallita");
        //res=bluetoothGatt.writeCharacteristic(characteristic);
    }
    sem.release();

        }
    }).start();
}

I used semaphore because if I do a write before that ondescriptorwrite is invoked the write fails, but I wonder if in this way I can lose some notifications..

Is The semaphore used in right way ? Or it can create some problem to me ?

1

There are 1 answers

2
Rob Gorman On BEST ANSWER

I think your semaphore pattern can work. But if you do it like this, you should set a timeout that clears the semaphore in case you never get the response. This is certainly possible as the device may have moved out of range or powered down (or even crashed).

Another possibility is to use the command design pattern and create a command queue to queue up commands when there is more than one.