Устройство BLE не может отправить несколько уведомлений GATT подряд

Я экспериментирую с Bluetooth LE с GATT и столкнулся с проблемой, с которой мне нужна ваша помощь.

Я отправляю данные туда и обратно между клиентом (одно приложение для Android и одно приложение для iOS) и сервером (в настоящее время работает Bleno).

Я выбрал архитектуру только с одной характеристикой (которую я считаю сокетом) и пишу на ней запросы от клиентов. Сервер отвечает на запрос уведомлением. Уведомления могут быть длиной всего 20 байт, поэтому иногда мне приходится разбивать ответ на несколько фрагментов и отправлять их как отдельные уведомления.

Моя проблема в том, что когда я разбиваю ответ на 10 или более фрагментов, они никогда не получаются на клиентах. (Для 1..9 чанков все работает как положено).

Я использовал HCIDump (hcidump -i hci0 -X) для проверки команд, отправленных через BLE, как в случае сбоя, так и в случае успеха.

Следующие выходные данные берутся из HCIDump при успешной отправке уведомлений:

< ACL data: handle 69 flags 0x00 dlen 27
ATT: Handle notify (0x1b)
  handle 0x000c
  value 0x06 0x09 0x46 0x46 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47

followed by:

> HCI Event: Number of Completed Packets (0x13) plen 5
handle 69 packets 1

(для каждого блока уведомлений)

Следующий вывод берется из HCIDump при невозможности отправки уведомлений:

< ACL data: handle 68 flags 0x00 dlen 27
ATT: Handle notify (0x1b)
  handle 0x000c
  value 0x08 0x0a 0x46 0x46 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47 0x47

Но я не получаю событий «Завершенные пакеты», а вместо этого просто device: disconnected.

Мне еще предстоит выяснить, на какой стороне связи возникает ошибка. Насколько я знаю, это может быть либо из-за того, что клиенты не могут получать и подтверждать уведомления «достаточно быстро», либо из-за того, что я ставлю в очередь слишком много запросов на стороне сервера.

Я пробовал добавлять команды Sleep() между отправкой каждого уведомления на сервер. Он работает, но чувствует себя слишком нестабильно. Для 10 уведомлений мне потребовалась задержка 6 мс, чтобы уведомления пришли, для 30 уведомлений мне потребовалась задержка 10 мс.

Кто знает с чего начать искать проблему? Я рад предоставить дополнительную информацию, если это необходимо.

Примечания:

  • Я протестировал и обнаружил точно такие же ограничения на своем устройстве Android и iOS.

person Joakim    schedule 17.03.2016    source источник


Ответы (1)


Существует ограничение на количество «кусков», которые вы можете отправить, прежде чем очередь будет заполнена. Вы должны дождаться, пока центральный сервер подтвердит, что он готов принять больше данных, прежде чем отправлять следующий фрагмент.

В случае с bleno вы должны подождать, чтобы получить указание в обратном вызове onIndicate вашей характеристики, прежде чем отправлять следующий фрагмент:

var Characteristic = bleno.Characteristic;

var characteristic = new Characteristic({
    uuid: 'fffffffffffffffffffffffffffffff1',
    properties: [ ... ],
    secure: [ ... ],
    value: null,
    onIndicate: null // <-- Right here
});

По крайней мере, для iOS вам не нужно менять свою реализацию, чтобы вернуть индикацию. Пока вы вызываете setNotifyValue:forCharacteristic:, вы также включаете индикацию в соответствии с документацией Apple:

Задает уведомления или указания для значения указанной характеристики.

Я не уверен, что для Android требуется дополнительная работа.

person mattsson    schedule 01.11.2016
comment
К сожалению, я не могу проверить, работает это или нет, так как мы больше не используем Bleno. Но звучит очень здраво. - person Joakim; 01.11.2016