Я работаю над сенсорным устройством BluetoothLE, для которого мне нужно сформировать широковещательную передачу данных "один ко многим". Согласно спецификации, периферийные устройства могут иметь только один мастер, и из-за ограничений чипа и стека, которые я проектирую, мастер может иметь только три подчиненных устройства. Из того, что я понимаю, Android не может стать ведомым BLE в любом случае, поэтому наличие моего устройства в качестве мастера не является вариантом.
В спецификации BT4 и документации производителя говорится о другом режиме работы, называемом широковещательным режимом. В широковещательном режиме соединение никогда не выполняется, а данные приложения передаются как часть рекламного пакета. Это точно соответствует моим потребностям, так как многие телефоны Android/iOS могут одновременно сканировать каждый пакет. Рекламный пакет передается несколько раз в пакетах, поэтому я подозреваю, что получение данных будет в основном надежным. Если пакет потерян здесь и там, его можно терпеть.
Когда это становится интересным, я хочу, чтобы эти пакеты несли данные датчиков в реальном времени, которые обновляются со скоростью 10-20 Гц. Из примеров, которые я нашел в Интернете, BLE в этом режиме в основном используется для реализаций типа iBeacon, где они передают статические данные. Я не могу найти никакой информации о том, как пакеты рекламы отфильтровываются в стеке Android. Возможно, они возвращают один результат на аппаратный адрес Bluetooth, или это может быть уникальная комбинация адресов и данных. Второй вариант будет работать для этого приложения. Если запуск и остановка сканирования сбрасывает фильтр, я могу заставить что-то работать.
В документации на Android ничего не говорится о том, как работает фильтрация устройств в методе сканирования. Я смог найти одно сообщение в сети, пытающееся решить эту же проблему, которая имеет нерешенный ответ: BLE: множественное обнаружение того же периферийного устройства во время сканирования. В iOS мой коллега сообщает мне, что есть параметр, который может быть передан функции сканирования, что делает это возможным.
Я попытался отследить код из вызова startLeScan() в источнике Android, но код довольно сложный, и использование абстракции затруднило определение реализации объекта, который его содержит. Самое дальнее, что я получил, - это объект IBluetoothGatt, возвращенный из метода класса BluetoothManagerService getBluetoothGatt(). Этот объект получает запрос на запуск сканирования. Он создается в строке 790 BluetoothManagerService.java в текущей версии live on github. Объект отбрасывается из результата сообщения, поэтому я подозреваю, что в результате возникает конкретный телефон/драйвер. Я не знаю, как это сделать.
Еще один вопрос, который я хотел бы решить, - это то, как быстро сканирование можно включать и выключать. Сканирование - это интенсивная работа, но передача данных будет происходить периодически на довольно точном таймере реального времени. В результате было бы большой оптимизацией, если сканирование можно включить и выключить, чтобы синхронизация и сканирование синхронизировались, а сканер отключил остальные 90% + времени. Вероятно, это необходимо будет испытать экспериментально.
Я все еще занимаюсь технико-экономическим исследованием, чтобы узнать, возможно ли это для нашего аксессуара для Android. Мой нынешний телефон еще не может запустить версию 4.3, поэтому у меня нет возможности проверить/взломать это экспериментально.