Как узнать, было ли подтверждено указание BLE в Android

Мы работаем над связью Bluetooth Low Energy между двумя приложениями Android. Один периферийный/серверный, другой центральный/клиентский. Сервер отправит клиентам уведомление, если данные изменились. Однако мы не нашли способа убедиться, что данные действительно подтверждаются на стороне клиента. Как мы можем выяснить, получил ли клиент и подтвердил данные, чтобы соответствующим образом отреагировать на них на стороне сервера?

Согласно документации Android, для BleutoothGattServer существует обратный вызов onNotificationSent. https://developer.android.com/reference/android/bluetooth/BluetoothGattServerCallback#onNotificationSent(android.bluetooth.BluetoothDevice,%20int)

Однако при отладке и выполнении некоторых тестов кажется, что этот метод действительно просто вызывается, если уведомление отправлено. Нет никакой гарантии, что сообщение действительно было получено или подтверждено.

Итак, вот как мы настраиваем характеристики для GattServer

BluetoothGattService service = new BluetoothGattService(SERVICE_LOGIN_UUID,
                BluetoothGattService.SERVICE_TYPE_PRIMARY);

        // Write characteristic
        BluetoothGattCharacteristic writeCharacteristic = new BluetoothGattCharacteristic(CHARACTERISTIC_LOGIN_UUID,
                BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_READ| BluetoothGattCharacteristic.PROPERTY_INDICATE,
                // Somehow this is not necessary, the client can still enable notifications
//                        | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);

        service.addCharacteristic(writeCharacteristic);

        mGattServer.addService(service);

а затем мы уведомляем клиентов, вызывая это

mHandler.post(() -> {
            BluetoothGattService service = mGattServer.getService(SERVICE_LOGIN_UUID);
            BluetoothGattCharacteristic characteristic = service.getCharacteristic(uuid);
            log("Notifying characteristic " + characteristic.getUuid().toString()
                    + ", new value: " + StringUtils.byteArrayInHexFormat(value));

            characteristic.setValue(value);
            boolean confirm = BluetoothUtils.requiresConfirmation(characteristic);
            for(BluetoothDevice device : mDevices) {
                mGattServer.notifyCharacteristicChanged(device, characteristic, confirm);
            }
        });

*ПОЖАЛУЙСТА, ПОКА ИГНОРИРУЙТЕ ЗДЕСЬ ЦИКЛ FOR

Это приведет к вызову onNotificationSent, но не поможет узнать, было ли оно подтверждено или нет.

Дайте мне знать, если вам нужны другие части кода.

Всем уже спасибо, большой привет


person Hardcore_Graverobber    schedule 08.02.2019    source источник
comment
Непонятно, какого рода «Подтверждение» вы ищете. Их существует несколько уровней на разных уровнях стека спецификаций Bluetooth. В любом случае, для уведомлений/индикации Bluetooth LE гарантирует либо доставку сообщения, либо разрыв соединения.   -  person bavaza    schedule 12.02.2019


Ответы (1)


К сожалению, на Android подтверждение отправляется/получается за кулисами, т.е. нет механизма, с помощью которого вы могли бы использовать это в своем приложении. Пожалуйста, взгляните на следующую ссылку: -

Обработка указаний вместо уведомлений в Android BLE

Если вы действительно хотите, чтобы какой-то механизм уровня приложения подтверждал, что данные были получены, вы можете реализовать другую (дополнительную) характеристику на стороне вашего сервера. Когда данные получены на центральной стороне, она может просто записать эту характеристику, чтобы доказать, что она есть. Это имеет тот недостаток, что делает ваше приложение более сложным, но, возможно, более надежным. Причина этого в том, что вы вручную отправляете подтверждения с уровня приложения, гарантируя, что все работает должным образом, в то время как автоматическая отправка ACK с уровня основной полосы частот не является доказательством того, что все работает на 100% успешно (например, данные не t сделать это от baseband к приложению, или ваше приложение потерпело крах и т. д.).

Надеюсь, это поможет.

person Youssif Saeed    schedule 13.02.2019