2017-05-15 14 views
3

1 Android phone(N5X 6.0.1)がBLEサーバーを実行していて、もう1つ(N5X O)がサブスクライブしています。特性のための 通知がしかし、有効にすることができ、書き込み記述部分に、私は一貫して他のすべてのUUIDがhereから作成された133BLE通知サブスクリプションを取得する133

Server.java

private void createServer() { 
    bluetoothGattServer = bluetoothManager.openGattServer(this, serverCallback); 
    BluetoothGattService service = new BluetoothGattService(Constants.SERVICE, 
     BluetoothGattService.SERVICE_TYPE_PRIMARY); 

    characteristic = 
     new BluetoothGattCharacteristic(Constants.CHARACTERISTIC, 
       BluetoothGattCharacteristic.PROPERTY_NOTIFY, 
       BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE); 

    // public static UUID DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); 
    characteristic.addDescriptor(new BluetoothGattDescriptor(Constants.DESCRIPTOR, 
       BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE)); 

    characteristic.setWriteType(
     BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); 

    service.addCharacteristic(characteristic); 
    bluetoothGattServer.addService(service); 
} 

private BluetoothGattServerCallback serverCallback = new BluetoothGattServerCallback() { 
    @Override 
    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { 
     super.onConnectionStateChange(device, status, newState); 
     Log.d(TAG, "onConnectionStateChange " + device.getName() + " " + status + " " + newState); 
     if (newState == BluetoothGatt.STATE_CONNECTED) { 
      bluetoothDevice = device; 
     } else if (newState == BluetoothGatt.STATE_DISCONNECTED) { 
      bluetoothGattServer.cancelConnection(bluetoothDevice); 
      bluetoothGattServer.close(); 
     } 
    } 
}; 

private void sendData(String message) { 
    characteristic.setValue(message); 
    bluetoothGattServer.notifyCharacteristicChanged(bluetoothDevice, characteristic, true); 
} 

を取得しています。

Client.java

device.establishConnection(false) 
     .flatMap(bleConnection -> bleConnection.setupNotification(Constants.CHARACTERISTIC)) 
     .flatMap(onNotificationReceived -> onNotificationReceived) 
     .subscribe(data -> { 
      Log.d(TAG, "data: " + data); 
     }, throwable -> { 
      Log.d(TAG, "data error " + throwable); 
     }); 

logcat

05-15 15:26:50.097 D/BluetoothGatt: setCharacteristicNotification() - uuid: 8d7dda32-3759-11e7-a919-92ebcb67fe33 enable: true 
05-15 15:26:50.105 D/RxBle#Radio: QUEUED RxBleRadioOperationDescriptorWrite(60042487) 
05-15 15:26:50.110 D/RxBle#Radio: FINISHED RxBleRadioOperationServicesDiscover(231218312) 
05-15 15:26:50.112 D/RxBle#Radio: STARTED RxBleRadioOperationDescriptorWrite(60042487) 
05-15 15:27:20.119 D/RxBle#Radio: FINISHED RxBleRadioOperationDescriptorWrite(60042487) 
05-15 15:27:20.121 D/BluetoothGatt: setCharacteristicNotification() - uuid: 8d7dda32-3759-11e7-a919-92ebcb67fe33 enable: false 
05-15 15:27:20.126 D/RxBle#BluetoothGatt: onDescriptorWrite descriptor=00002902-0000-1000-8000-00805f9b34fb status=133 
05-15 15:27:20.129 D/BLE: data error BleGattDescriptorException{macAddress=42:EE:5A:C6:C1:F0, status=133 (0x85 -> https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-5.1.0_r1/stack/include/gatt_api.h), bleGattOperationType=BleGattOperation{description='DESCRIPTOR_WRITE'}} 

注:私はネイティブのAndroid APIを使用していた場合、私は記述子に記述することなく、通知をサブスクライブして受信することができますよ。

update:面白いことですが、書き込み記述子プロセスが起きている間に(エラーで戻ってくるまで約30秒かかる)、onCharacteristicChangedを受け取ることができます。

アップデート2:追加のコールバックと特性コードへの書き込み

答えて

3

のBluetoothコア仕様は特性が通知をサポートしている場合、それはクライアント特性コンフィグ記述が含まれているとCCC記述子が適切な値が書き込まれるときにのみ通知開始すべきであると述べています。

あなたの設定には、status = 133というマニフェストの問題があるようです。 characteristicのプロパティを設定するときに間違いをした可能性があります。私はあなたが、読み取り、書き込み、および通知を設定することができます特性を持つようにしたいと仮定 - このような状況では、それは次のようになります。編集

characteristic = 
    new BluetoothGattCharacteristic(Constants.CHARACTERISTIC, 
      BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_NOTIFY, 
      BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE); 

- 中央、通知にそれを回すために要求している場合ことを覚えておいてくださいクライアントの特性設定記述子を書き込もうとしています。 NO_RESPONSEの設定が要求されていない限り、セントラルは応答を期待しています。

適切な解決策がonDescriptorWriteRequestにコールバックを追加し、中央への応答を送信することです:

BluetoothGattServerCallback serverCallback = new BluetoothGattServerCallback() { 
    // (...) 

    @Override 
    public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, 
             boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) { 
     super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value); 

     // validate if the request is exactly what you expect if needed 
     bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value); 
    } 

    // (...) 
}; 

潜在的な回避策

いくつかの中国メーカーは、Bluetoothコア仕様と、それらに準拠していません通知を送信している特性の下にCCC記述子がない。 CCCを設定せずに通知を受け取ることができる場合は、互換モードRxBleConnection.setupNotifications(characteristic, NotificationSetupMode.COMPAT)を使用することはできますが、これは推奨されませんが、設定への適切な修正が必要です。

+0

推奨される修正では問題は解決されませんでしたが、回避策がありました。 – mbmc

+0

'BluetoothGattServer'設定に別の問題があるはずです。私は両方のAndroid OSがうまくいっていると思いますが、回避策は回避策です。明日は、Androidとしてサーバとして遊ぶ瞬間があるかもしれません。編集をありがとう - 私にとっては早すぎました。 –

+0

@mbmc 'BluetoothGattServerCallback'コードを共有できますか?私はあなたが中央への反応を適切に管理していないと思います。 –

関連する問題