2016-12-01 180 views
0

我想從Xamarin Android應用程序中讀取藍牙LE特徵。來自Xamarin的藍牙LE特徵Android

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(); 
    } 

我的問題是我的public async Task<BluetoothGattCharacteristic> GetCharecteristic(int timeout,BluetoothGattCharacteristic characteristic) 功能

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

回答

1

有死鎖的方法可行裏面?

如果同時調用m_gatt.readCharacteristic(gattCharacteristic);m_gatt.writeCharacteristic(gattCharacteristic);方法,則可能導致死鎖。因爲您可以使用兩個SemaphoreSlim同時更改m_characteristic。使用一個SemaphoreSlim可以解決死鎖如下面的代碼:

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(); 
    } 

有沒有爲我檢查,如果該屬性是(法定)啓用通知

可以使用返回之前的方式檢查的setCharacteristicNotification值如下的代碼,如果該屬性是(法定):

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

但你打電話之前setCharacte ristic通知沒有方法檢查屬性是否(通知)。