BluetoothPeripheral { public boolean writeDescriptor(@NotNull final BluetoothGattDescriptor descriptor, @NotNull final byte[] value) { Objects.requireNonNull(descriptor, "no valid descriptor provided"); Objects.requireNonNull(value, "no valid value provided"); if (bluetoothGatt == null) { Timber.e("gatt is 'null', ignoring write descriptor request"); return false; } final byte[] bytesToWrite = copyOf(value); boolean result = commandQueue.add(new Runnable() { @Override public void run() { if (isConnected()) { currentWriteBytes = bytesToWrite; descriptor.setValue(bytesToWrite); if (!bluetoothGatt.writeDescriptor(descriptor)) { Timber.e("writeDescriptor failed for descriptor: %s", descriptor.getUuid()); completedCommand(); } else { Timber.d("writing <%s> to descriptor <%s>", bytes2String(bytesToWrite), descriptor.getUuid()); nrTries++; } } else { completedCommand(); } } }); if (result) { nextCommand(); } else { Timber.e("could not enqueue write descriptor command"); } return result; } BluetoothPeripheral(@NotNull Context context, @NotNull BluetoothDevice device, @NotNull InternalCallback listener, BluetoothPeripheralCallback peripheralCallback, Handler callbackHandler); boolean createBond(); boolean requestConnectionPriority(final int priority); void cancelConnection(); @NotNull String getAddress(); int getType(); String getName(); int getBondState(); @SuppressWarnings("WeakerAccess") @NotNull List<BluetoothGattService> getServices(); @Nullable BluetoothGattService getService(@NotNull UUID serviceUUID); @Nullable BluetoothGattCharacteristic getCharacteristic(@NotNull UUID serviceUUID, @NotNull UUID characteristicUUID); int getState(); int getCurrentMtu(); boolean isNotifying(@NotNull BluetoothGattCharacteristic characteristic); boolean readCharacteristic(@NotNull final BluetoothGattCharacteristic characteristic); boolean writeCharacteristic(@NotNull final BluetoothGattCharacteristic characteristic, @NotNull final byte[] value, final int writeType); boolean readDescriptor(@NotNull final BluetoothGattDescriptor descriptor); boolean writeDescriptor(@NotNull final BluetoothGattDescriptor descriptor, @NotNull final byte[] value); boolean setNotify(@NotNull final BluetoothGattCharacteristic characteristic, final boolean enable); boolean clearServicesCache(); boolean readRemoteRssi(); boolean requestMtu(final int mtu); @SuppressWarnings("WeakerAccess")
    static final int GATT_SUCCESS; @SuppressWarnings("WeakerAccess")
    static final int GATT_CONN_L2C_FAILURE; @SuppressWarnings("WeakerAccess")
    static final int GATT_CONN_TIMEOUT; @SuppressWarnings("WeakerAccess")
    static final int GATT_READ_NOT_PERMITTED; @SuppressWarnings("WeakerAccess")
    static final int GATT_WRITE_NOT_PERMITTED; @SuppressWarnings("WeakerAccess")
    static final int GATT_INSUFFICIENT_AUTHENTICATION; @SuppressWarnings("WeakerAccess")
    static final int GATT_REQUEST_NOT_SUPPORTED; @SuppressWarnings("WeakerAccess")
    static final int GATT_INSUFFICIENT_ENCRYPTION; @SuppressWarnings("WeakerAccess")
    static final int GATT_CONN_TERMINATE_PEER_USER; @SuppressWarnings("WeakerAccess")
    static final int GATT_CONN_TERMINATE_LOCAL_HOST; @SuppressWarnings("WeakerAccess")
    static final int GATT_CONN_LMP_TIMEOUT; @SuppressWarnings("WeakerAccess")
    static final int BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE; @SuppressWarnings("WeakerAccess")
    static final int GATT_CONN_FAIL_ESTABLISH; @SuppressWarnings("WeakerAccess")
    static final int GATT_NO_RESOURCES; @SuppressWarnings("WeakerAccess")
    static final int GATT_INTERNAL_ERROR; @SuppressWarnings("WeakerAccess")
    static final int GATT_BUSY; @SuppressWarnings("WeakerAccess")
    static final int GATT_ERROR; @SuppressWarnings("WeakerAccess")
    static final int GATT_AUTH_FAIL; @SuppressWarnings("WeakerAccess")
    static final int GATT_CONN_CANCEL; @SuppressWarnings("WeakerAccess")
    static final int DEVICE_TYPE_UNKNOWN; @SuppressWarnings("WeakerAccess")
    static final int DEVICE_TYPE_CLASSIC; @SuppressWarnings("WeakerAccess")
    static final int DEVICE_TYPE_LE; @SuppressWarnings("WeakerAccess")
    static final int DEVICE_TYPE_DUAL; @SuppressWarnings("WeakerAccess")
    static final int BOND_NONE; @SuppressWarnings("WeakerAccess")
    static final int BOND_BONDING; @SuppressWarnings("WeakerAccess")
    static final int BOND_BONDED; @SuppressWarnings("WeakerAccess")
    static final int STATE_DISCONNECTED; @SuppressWarnings("WeakerAccess")
    static final int STATE_CONNECTING; @SuppressWarnings("WeakerAccess")
    static final int STATE_CONNECTED; @SuppressWarnings("WeakerAccess")
    static final int STATE_DISCONNECTING; }
@Test public void writeDescriptor() { BluetoothGattCallback callback = connectAndGetCallback(); callback.onConnectionStateChange(gatt, GATT_SUCCESS, STATE_CONNECTED); BluetoothGattService service = new BluetoothGattService(SERVICE_UUID, 0); BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(UUID.fromString("00002A1C-0000-1000-8000-00805f9b34fb"),PROPERTY_INDICATE,0); BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(UUID.fromString("00002903-0000-1000-8000-00805f9b34fb"),0); service.addCharacteristic(characteristic); characteristic.addDescriptor(descriptor); when(gatt.getServices()).thenReturn(Arrays.asList(service)); byte[] originalByteArray = new byte[]{0x01}; peripheral.writeDescriptor(descriptor, originalByteArray); verify(gatt).writeDescriptor(descriptor); callback.onDescriptorWrite(gatt, descriptor, 0); ArgumentCaptor<BluetoothPeripheral> captorPeripheral = ArgumentCaptor.forClass(BluetoothPeripheral.class); ArgumentCaptor<byte[]> captorValue = ArgumentCaptor.forClass(byte[].class); ArgumentCaptor<BluetoothGattDescriptor> captorDescriptor = ArgumentCaptor.forClass(BluetoothGattDescriptor.class); ArgumentCaptor<Integer> captorStatus = ArgumentCaptor.forClass(Integer.class); verify(peripheralCallback).onDescriptorWrite(captorPeripheral.capture(), captorValue.capture(), captorDescriptor.capture(), captorStatus.capture()); byte[] value = captorValue.getValue(); assertEquals(0x01, value[0]); assertNotEquals(value, originalByteArray); assertEquals(peripheral, captorPeripheral.getValue()); assertEquals(descriptor, captorDescriptor.getValue()); assertEquals(GATT_SUCCESS, (int) captorStatus.getValue() ); }