BLE通知订阅获得133

时间:2017-05-15 22:38:42

标签: android bluetooth-lowenergy rxandroidble

1 Android手机(N5X 6.0.1)正在运行BLE服务器,另一个(N5X O)正在订阅。 可以启用特征通知,但是在写描述符部分,我一直得到133。

Transition.ts import {trigger, state, animate, style, transition} from '@angular/core'; export function optionsTransition() { return trigger('optionsTransition', [ state('enter', style({transform: 'translateZ(-500px)'}) ), state('leave', style({transform: 'translateZ(0)'}) ), transition(':enter', [ // style({transform: 'translateZ(-500px)',opacity:0}), animate('0.5s ease-in-out', style({transform: 'translateZ(0px)', opacity: 1})) ]), transition(':leave', [ // style({transform: 'translateZ(0px)',opacity:1}), animate('0.5s ease-in-out', style({transform: 'translateZ(-500px)', opacity: 0})) ]) ]);

Server.java

所有其他UUID都是从here创建的。

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

注意:如果我使用原生Android API,我可以订阅和接收通知,而无需写入描述符。

更新:有趣的是,虽然写描述符过程正在发生(它需要大约30秒,直到它返回错误),我能够接收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'}}

update2:添加了回调并写入特征代码

1 个答案:

答案 0 :(得分:4)

蓝牙核心规范表示,如果某个特性支持通知,它应该包含一个客户端特征配置描述符,并且仅在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);
    }

    // (...)
};

潜在的解决方法

一些中国制造商不符合蓝牙核心规范,并且在发送通知的特性下没有CCC描述符。如果您能够在不设置CCC的情况下收到通知,那么您可以使用兼容模式RxBleConnection.setupNotifications(characteristic, NotificationSetupMode.COMPAT),但不建议使用兼容模式,并且应该对配置进行适当的修复。