简体   繁体   中英

Bluetooth LE characteristic from Xamarin Android

I am trying to read Bluetooth LE characteristic from Xamarin Android Application.

m_characteristicReady = new SemaphoreSlim(1);
m_characteristicChanged = new SemaphoreSlim(1);



 public async Task<BluetoothGattCharacteristic> GetCharecteristic(int timeout,BluetoothGattCharacteristic characteristic)
        {
            EnableCharacteristicNotification(characteristic);
            //Once notifications are enabled for a characteristic, 
            //an onCharacteristicChanged() callback is triggered if the characteristic changes on the remote device:
            m_characteristicChanged.Wait();

            //We serialize all requests and timeout only on requests themself cand not their predesesors
            m_characteristicReady.Wait();
           //todo check result ???
            m_gatt.ReadCharacteristic(characteristic);
            if (await m_characteristicReady.WaitAsync(timeout) == true || 
                await m_characteristicChanged.WaitAsync(timeout) == true)
            {
                m_characteristicChanged.Release();
                m_characteristicReady.Release();
                return m_characteristic;
            }
            return null;
        }

    public override void OnCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, [Android.Runtime.GeneratedEnum] GattStatus status)
    {
        m_characteristic = characteristic;
        m_characteristicReady.Release();
    }

    public override void OnCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
    {
        m_characteristic = characteristic;
        m_characteristicChanged.Release();
    }

My question is inside my public async Task<BluetoothGattCharacteristic> GetCharecteristic(int timeout,BluetoothGattCharacteristic characteristic) function

1) is there a possiblity of a deadlock?

2) Is there a way for me to check if the attribute is (notifiable) before enabling notification

is there a possiblity of a deadlock?

If both m_gatt.readCharacteristic(gattCharacteristic); and m_gatt.writeCharacteristic(gattCharacteristic); methods are invoked asynchronously, it may lead a deadlock. Because you may change m_characteristic at the same time by using two SemaphoreSlim . Use one SemaphoreSlim can solve the deadlock as the following code:

    public async Task<BluetoothGattCharacteristic> GetCharecteristic(int timeout, BluetoothGattCharacteristic characteristic)
    {
        EnableCharacteristicNotification(characteristic);            
        m_gatt.ReadCharacteristic(characteristic);                 
        return m_characteristic;
    }

    public override void OnCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, [Android.Runtime.GeneratedEnum] GattStatus status)
    {
        m_SemaphoreSlim.Wait();
        m_characteristic = characteristic;
        m_SemaphoreSlim.Release();
    }

    public override void OnCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
    {
        m_SemaphoreSlim.Wait();
        m_characteristic = characteristic;
        m_SemaphoreSlim.Release();
    }

Is there a way for me to check if the attribute is (notifiable) before enabling notification

You can use the return value of setCharacteristicNotification as following code to check if the attribute is (notifiable):

       boolean isEnableNotification = mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
       if (isEnableNotification)
       {
       //.....
       }

But before you call setCharacteristicNotification there is no method to check if the attribute is (notifiable).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM