2013-10-02 6 views
2

Основная проблема, которую я пытаюсь решить, заключается в следующем. У меня есть два устройства iOS, один из которых сконфигурирован как центральный, а другой - как периферийный. Я хотел бы, чтобы периферийное устройство узнало, если центральный элемент уходит или становится неактивным по какой-либо причине (например, устройство, на котором запущено центральное устройство, отключено).CoreBluetooth: Как может периферийный менеджер узнать, что центральный получил указание?

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

Однако, чтобы поймать условие угла, когда центральное устройство переходит из CLProximityImmediate в какое-то неизвестное состояние, я планировал использовать периодические указания от периферии, на которую может ответить центральный. Если нет никакого ответа на указание, тогда периферийное устройство может предположить, что центральное устройство больше не находится в непосредственной близости. Однако я не могу найти метод обратного вызова или делегирования, который информирует периферийного менеджера о том, что индикация не удалась.

Метод updateValue: forCharacteristic: onSubscribedCentrals: возвращает NO, когда основная очередь передачи заполнена - и НЕ, потому что центральный не ответил, как я ее понял.

Я пропустил что-то очевидное здесь? Есть ли способ для периферийного менеджера сказать, что центральный не получил указание? Или в этом случае отсутствует обратный вызов в CoreBluetooth?

Благодарим за помощь!

+0

Что делать, если вместо этого вы используете уведомление и таймер? Хороший вопрос. – allprog

ответ

5

Есть два вопроса, чтобы окружные знать местоположение maneager потеряло контакт с CLBeacon:

  1. В iBeacons пассивен, рекламировать и передавать только устройство. Как и в реализации Apple, соединение из них с базой Core Location отсутствует. Поэтому периферийный новичок знает, что кто-то слушал их трансляцию.

  2. CLBeacon не будет раскрывать базовое периферийное устройство BTLE как CBPeripheral, поэтому вы не сможете позволить периферийному устройству BTLE знать, что ваш монитор местоположения находится в зоне действия.

Выпуск № 2 может быть решена довольно сложный путь:

  1. Начать сканирование CBPeripherals где advertisementData содержит proximityUUID.

  2. Подключитесь к этому CBPeripheral и получите уведомление об изменении стоимости характеристики.

  3. Часто изменяйте значение характеристики на периферийном устройстве, поэтому, когда Central не видит больше уведомлений после периода ожидания, это указывает на то, что периферийное устройство выходит за пределы допустимого диапазона.

  4. Если вы хотите, чтобы он работал на нескольких устройствах iOS, это затрудняет переход между рекламой и iBeacon и работает как периферийное устройство GATT.

3

Хотя это явно не указано в вопросе, я неявно заявлял, что периферийное устройство рекламирует услугу с несколькими характеристиками. Это в дополнение к явной рекламе iBeacon, которая, я согласна, является «пассивной». Когда центральный сигнал уведомляется о зоне маяка, он обнаруживает и записывает одну из характеристик, а периферийное устройство может знать, что центральный находится в зоне действия.

Мой фундаментальный вопрос заключается не в пассивном характере маяка, а в том, как «указания» работают с CoreBluetooth. Я считаю, что можно с уверенностью сказать, что если периферийное устройство использует updateValue:forCharacteristic:onSubscribedCentrals:, чтобы проинформировать центральную сторону, подписанную на характеристику, определенную как CBCharacteristicPropertyIndicate, нет обратного вызова, предназначенного для подтверждения подтверждения на индикацию, которая должна возвращаться из центральной (за GAP).

Одним из обходных путей для этого недостающего API является определение третьей характеристики в качестве характеристики «подтверждения» и наложение протокола, в соответствии с которым центральный должен делать фиктивный считывание по этому признаку всякий раз, когда центральный принимает peripheral:didUpdateValueForCharacteristic: на указание, которое было подписано. Это должно вызвать вызов peripheralManager:didReceiveReadRequest: на периферийном устройстве, чтобы подтвердить, что индикация получена.

Это больше работа, а не самый элегантный способ сделать это, но это может быть лучше всего, если у вас нет API для подтверждения показаний.

+0

Ваш ответ действительно помогает и, кажется, подходит для работы. Итак, если реклама маяков является пассивной, мы никак не можем иметь что-то вроде «сессии» между конкретным маяком и центральным устройством? Или есть? –

+0

Можно провести сеанс между периферийной рекламой маяка и центральной. Для этого центральное место должно быть на переднем плане, однако, чтобы подключиться к устройству, рекламируя маяк, и обнаруживать другие сервисы. В фоновом режиме это в настоящее время не работает. См. Мой ответ на другой связанный с этим вопрос в отношении фона и CoreBluetooth: http://stackoverflow.com/questions/9896562/what-exactly-can-corebluetooth-applications-do-whilst-in-the-background/19458200#19458200 – user108

+0

Спасибо для вашего комментария и ссылки. Я прочитал ваш другой ответ. Однако я все еще уверен, как можно реализовать «сеанс». По сеансу вы пытаетесь сказать, что предлагает вышеупомянутый ответ? i.e Запись на другую характеристику, чтобы сообщить статус сессии ... –

Смежные вопросы