Как исправить проблемы с сопряжением по Bluetooth
Соединение по Bluetooth — хороший способ перекинуть файлы с одного устройства на другое или подключить беспроводные гаджеты друг к другу. Но иногда возникают проблемы с сопряжением. Рассказываем, что делать, если подключение по Bluetooth не работает.
В целом, Bluetooth имеет обратную совместимость: устройства, поддерживающие стандарт Bluetooth 5.0, по-прежнему могут сопрягаться с устройствами, использующими, скажем, древний Bluetooth 2.1, вышедший еще в 2007 году.
Исключение составляют гаджеты, которые используют версию с низким энергопотреблением под названием Bluetooth Low Energy, которая работает по другому протоколу, нежели старые или «классические» устройства Bluetooth. Устройства с BLE не обладают обратной совместимостью и не распознают старые устройства, поддерживающие классический Bluetooth. Обычно BLE-девайсы — это метки, фитнес-браслеты и пр.
Если устройство поддерживает Bluetooth 4.0, 4.2 или 5.0, оно должно распознавать в том числе и Bluetooth LE
Что можно сделать, если соединение по Bluetooth не работает?
1. Убедиться, что Bluetooth активен, а устройства сопряжены и находятся на близком расстоянии друг от друга. Иногда для сопряжения требуется ввести код в смартфоне или ПК.
2. Включить режим видимости. Часто это касается фитнес-браслетов и информационно-развлекательной системы автомобиля — пользователи забывают активировать режим видимости.
3. Выключить и снова включить оба устройства либо соединение Bluetooth — как ни странно, но это до сих пор один из самых работающих методов.
4. Удалить старые подключения. Иногда гаджеты поддерживают только одно подключение — особенно часто это касается беспроводных колонок. Так что вы можете пытаться подключить динамик к планшету, в то время как он успешно сопрягается с устройством, с которым соединился в последний раз, например, со смартфоном. Выключите на время этот девайс или удалите у него подключение.
5. Зарядить оба устройства, которые пытаетесь связать. Некоторые гаджеты поддерживают интеллектуальное управление питанием, которое может отключать Bluetooth, если уровень заряда батареи слишком низкий.
6. Удалить устройство со смартфона и найти заново. В настройках iOS вы можете удалить устройство, нажав на его имя, а затем «Забыть это устройство». На Android коснитесь имени устройства и затем «Разорвите пару». Если речь идет о системе автомобиля, может потребоваться выключить зажигание, открыть и закрыть дверь авто и подождать пару минут, прежде чем пытаться снова выполнить сопряжение.
7. Отойти от источников помех. Очень редко, но могут мешать сигналы от других устройств, например, Wi-Fi-роутера, порта USB 3.0. Помехой может стать даже усиленный чехол для смартфона.
8. Обновить драйверы и прошивку оборудования.
9. Очистить кэш Bluetooth. Иногда приложения могут мешать работе Bluetooth и очистка кэша может решить проблему. В Android-устройствах этот раздел находится в настройках системы: «Система» — «Дополнительно» — «Сбросить параметры» — «Сбросить настройки Wi-Fi, мобильного телефона и Bluetooth». На iOS понадобится разорвать пару со всеми устройствами (перейдите в «Настройки» — Bluetooth, выберите значок информации и «Забыть это устройство» для каждого девайса), затем перезагрузить гаджет.
Bluetooth: технология и ее применение
Что же такое Bluetooth? Это технология беспроводной связи, созданная в 1998 году группой компаний: Ericsson, IBM, Intel, Nokia, Toshiba. В настоящее время разработки в области Bluetooth ведутся Bluetooth SIG (Special Interest Group), в которую входят также Lucent, Microsoft и многие другие.
Интерфейс Bluetooth позволяет передавать как голос (со скоростью 64 Кбит/сек), так и данные. Для передачи данных могут быть использованы асимметричный (721 Кбит/сек в одном направлении и 57,6 Кбит/сек в другом) и симметричный методы (432,6 Кбит/сек в обоих направлениях). Работающий на частоте 2.4 ГГц приемопередатчик, коим является Bluetooth-чип, позволяет в зависимости от степени мощности устанавливать связь в пределах 10 или 100 метров. Разница в расстоянии, безусловно, большая, однако соединение в пределах 10 м позволяет сохранить низкое энергопотребление, компактный размер и достаточно невысокую стоимость компонентов. Так, маломощный передатчик потребляет всего 0.3 мА в режиме standby и в среднем 30 мА при обмене информацией.
Частотный диапазона Bluetooth в большинстве стран свободен от лицензирования, но во Франции, Испании и Японии из-за законодательных ограничений необходимо использовать отличные от указанных выше частоты.
Часто приходится сталкиваться с мнением, что находящиеся в пределах действия связи Bluetooth-устройства могут просто соединиться и начать обмениваться информацией, которая, возможно, не предназначена для сторонних ушей или глаз. На самом деле автоматический обмен информацией между Bluetooth-устройствами ведется лишь на уровне аппаратного обеспечения, т.е. исключительно для определения самого факта возможности соединения. А вот на уровне приложений пользователь сам решает, ввести или запретить автоматическую установку связи. Таким образом, использование Bluetooth становится не опаснее подключения к Интернету, в котором все узлы также соединены электрически, но это еще не означает получение безоговорочного доступа к любому ресурсу.
Стоит также заметить, что стандарт Bluetooth разрабатывался с расчетом на малую мощность, поэтому воздействие его на организм человека сведено к минимуму.
Основным направлением использования Bluetooth должно стать создание так называемых персональных сетей (PAN, или private area networks), включающих такие разноплановые устройства, как мобильные телефоны, PDA, МР3-плееры, компьютеры и даже микроволновые печи с холодильниками (вот уж что давно не подключали в сеть ). Возможность передачи голоса позволяет встраивать интерфейс Bluetooth в беспроводные телефоны или, например, беспроводные гарнитуры для сотовых телефонов. Возможности применения Bluetooth на практике безграничны: помимо синхронизации PDA с настольным компьютером или подсоединения относительно низкоскоростной периферии вроде клавиатур или мышей интерфейс позволяет очень просто и с небольшими затратами организовать домашнюю сеть. Причем узлами этой сети могут быть любые устройства, имеющие потребность в информации либо обладающие необходимой информацией.
Как легко заметить, интерфейс Bluetooth намного лучше приспособлен для использования в тех беспроводных устройствах связи, где требуется достаточно низкая цена, нет необходимости в высоких скоростях и желательно низкое энергопотребление. Однако, как уже отмечалось, возможно создание комбинированных сетей, тем более что IEEE 802.11 работает совершенно по другому принципу кодирования передаваемых данных, следовательно, находясь на одной и той же рабочей частоте, оба стандарта будут слышать друг друга физически, но чужие сигналы будут расценены каждым из них как посторонний шум.
Немаловажным аспектом в развитии Bluetooth является тот факт, что эта технология не подлежит лицензированию и ее использование не требует выплаты каких-либо лицензионных отчислений (хотя и требует подписания бесплатного соглашения). Такая политика позволила многим компаниям энергично включиться в процесс разработки устройств с интерфейсом Bluetooth, кои были в большом количестве продемонстрированы на выставке CeBIT 2001.
Наибольший интерес, естественно, вызывают устройства, обеспечивающие переход с уже существующих интерфейсов на Bluetooth. Одним из них стало Industrial Bluetooth Serial Port Adapter шведской компании connectBlue. Как видно из названия, это устройство предназначено для промышленного применения и позволяет подключать к Bluetooth любые приборы, оборудованные последовательным портом:
Типичным вариантом использования может стать, например, конфигурирование промышленных установок при помощи ноутбука.
Компания Belkin, знаменитая, в частности, своими продуктами для шины USB, представила целый набор устройств Bluetooth:
Здесь мы видим отличное USB решение для настольных (и не только) компьютеров: характеристики те же, что и в предыдущем случае, к тому же это устройство позволяет обмениваться данными по голосовым каналам.
Есть даже адаптер для Palm V: Palm просто кладется в него, как в стандартную кроватку, после чего можно синхронизироваться с настольным компьютером или выходить в Интернет при помощи мобильного телефона, также снабженного Bluetooth интерфейсом. Данный адаптер питается от батареи самого Palm’а.
На выставке можно было найти даже Bluetooth адаптер для Compact Flash:
Компания Troy XCD представила адаптер для подключения принтера с интерфейсом Centronics к Bluetooth:
А вот фотография его прототипа в работе:
3000AS представляет собой Linux-сервер, который может также работать как шлюз в локальную сеть или Интернет. В отличие от большинства других Bluetooth-устройств 3000AS имеет мощный приемопередатчик, обеспечивающий связь в пределах 100 м, причем в комплект входит внешняя антенна, повышающая надежность связи при наличии внешних помех. Для подключения можно использовать ISDN (с выбором вариантов «постоянно онлайн» или «подключение по требованию»), 10/100 Мбит Ethernet, а также RS-232 для сервисного применения. Сервер может также быть запитан через UPS.
Для расширения доступа к серверу могут использоваться малогабаритные точки доступа Red-M 1000AP:
Сервер автоматически определяет и конфигурирует все точки доступа, находящиеся в пределах дальности его действия. Внешние устройства могут быть подсоединены к точке доступа через 10/100 Мбит Ethernet.
Схожую систему представил MiTAC: их Bluetooth Access Point несет на борту 750МГц процессор Transmeta Crusoe TM5400, встроенный NAT и DHCP сервер и, как и предыдущий образец, мощный приемопередатчик дальностью действия до 100 м:
Распространенным вариантом является подключение стандартных устройств ввода через Bluetooth, например, вот так:
Sony представила на CeBIT специальный модуль в формате Memory Stick под названием InfoStick:
Очень неплохая идея, особенно учитывая наличие аналогичного устройства для Compact Flash.
Bluetooth LE не так уж и страшен, или Как улучшить пользовательский опыт без особых усилий
Недавно мы в команде придумали и реализовали функцию передачи денег по воздуху с помощью технологии Bluetooth LE. Я хочу рассказать вам, как мы это сделали и что Apple предоставляет нам из инструментов. Многие разработчики думают что Bluetooth — это сложно, ведь это достаточно низкоуровневый протокол, и по нему не так много специалистов. Но всё не так страшно, и на самом деле использовать эту функцию очень просто! А те функции, которые можно реализовать с помощью Bluetooth LE, безусловно, интересны и впоследствии позволят выделить ваше приложение среди конкурентов.
Давайте сначала разберёмся, что это вообще за технология и в чём её отличие от классического Bluetooth.
Что такое Bluetooth LE?
Почему разработчики Bluetooth назвали эту технологию именно Low Energy? Ведь с каждой новой версией Bluetooth энергопотребление и без того многократно снижалось. Ответ кроется в этой батарейке.
Её диаметр всего 2 см, а ёмкость около 220 мА*ч. Когда инженеры разрабатывали Bluetooth LE, они стремились к тому, чтобы устройство с такой батарейкой работало несколько лет. И у них это получилось! Bluetooth LE-устройства c таким элементом питания могут работать от года. Кто из вас еще по-старинке выключает Bluetooth на телефоне для экономии энергии, как это делали в 2000-м? Зря вы это делаете — экономия будет меньше 10 секунд работы телефона в день. А функциональность вы отключаете очень большую, такую как Handoff, AirDrop и другие.
Чего же инженеры добились, разработав Bluetooth LE? Они усовершенствовали классический протокол? Сделали его более энергоэфективным? Просто оптимизировали все процессы? Нет. Они полностью переделали архитектуру стека Bluetooth и добились того, что теперь, чтобы быть видимым для всех других устройств, необходимо меньше времени находиться в эфире и занимать канал. В свою очередь это позволило хорошо сэкономить на энергопотреблении. А с новой архитектурой теперь можно стандартизировать любое новое устройство, благодаря чему разработчики со всего мира могут коммуницировать с устройством, а значит, и с легкостью писать новые приложения для управления им. Кроме того, в архитектуру заложен принцип self-discovery: при подключении к устройству не нужно вводить никакие пин-коды, и если ваше приложение умеет общаться с этим устройством, подключение занимает считанные миллисекунды.
Частота осталась та же: 2,4 ГГц, не сертифицируемая и свободная для использования во многих странах. А вот задержка подключения стала меньше: 15-30 мс вместо 100 мс у классического Bluetooth. Расстояние работы осталось таким же — 100 м. Интервал передачи не сильно, но изменился — вместо 0,625 мс стало 3 мс.
Но не могло же из-за этого энергопотребление уменьшиться в десятки раз. Конечно же, что-то должно было пострадать. И это скорость: вместо 24 Мбит/с стало 0,27 Мбит/с. Вы, наверное, скажете, что это смешная скорость для 2018 года.
Где используется Bluetooth LE?
Технология эта немолодая, впервые она появилась в iPhone 4s. И уже успела завоевать много сфер. Bluetooth LE используется во всех устройствах умного дома и в носимой электронике. Сейчас уже есть даже чипы размером с кофейное зерно.
А как эта технология применяется в программном обеспечении?
Поскольку Apple была первой, кто встроил в своё устройство Bluetooth и начал её использовать, то к настоящему времени они достаточно хорошо продвинулись и встроили технологию в свою экосистему. И сейчас вы можете встретить эту технологию в таких сервисах, как AirDrop, Devices quick start, Share passwords, Handoff. И даже уведомления в часах сделаны через Bluetooth LE. Вдобавок, Apple выложила в открытый доступ документацию, как сделать так, чтобы на ваши собственные устройства приходили уведомления из всех приложений. Какие бывают роли устройств в рамках Bluetooth LE?
Broаdcaster. Отправляет сообщения всем, кто находится рядом, к этому устройству нельзя подключиться. По такому принципу работают iBeacons и навигация в помещениях.
Observer. Слушает, что происходит вокруг, и получает данные только от общедоступных сообщений. Соединения не создаёт.
А вот с Central и Peripheral интереснее. Почему их не назвали просто Server-Client? Логично же, судя по названию. А вот и нет.
Потому что Peripheral, на самом деле, выступает как сервер. Это периферийное устройство, которое потребляет меньше энергии и к которому подключается более мощный Central. Peripheral может извещать, что он находится рядом и какие у него есть службы. К нему может подключиться только одно устройство, и у Peripheral есть какие-то данные. А Central может сканировать эфир в поиске устройств, отправлять запросы на подключение, подключаться к любому количеству устройств, может читать, записывать и подписывать на данные у Peripheral.
Что же нам, как разработчикам, доступно в экосистеме Apple?
Что нам доступно?
Как работает протокол
Как происходит процесс поиска и подключения?
Peripheral сообщает о своем присутствии с частотой advertisement-интервала, его пакет очень маленький и содержит всего несколько идентификаторов сервисов, которые предоставляет устройство, а также имя устройства. Интервал может быть достаточно большим и способен варьироваться в зависимости от текущего статуса устройства, режима энергосбережения и других настроек. Apple советует разработчикам внешних устройств привязывать длину интервала к акселерометру: увеличивать интервал, если устройством не пользуются, а когда оно активно — уменьшать, чтобы быстро находить устройство. Advertisement-интервал никак не коррелирует c интервалом подключения и определяется самим устройством в зависимости от энергопотребления и своих настроек. Нам он в экосистеме Apple недоступен и неизвестен, им полностью управляет система.
После того, как мы нашли устройство, отправляем запрос на подключение, и вот тут на сцену выходит интервал подключения — время, через которое второе устройство может ответить на запрос. Но это при подключении, а что же происходит при чтении/записи?
Интервал подключения также фигурирует и при чтении данных — его уменьшение в 2 раза увеличивает скорость передачи данных. Но нужно понимать, что если оба устройства не поддерживают одинаковый интервал, то будет выбран максимальный из них.
Давайте рассмотрим, из чего состоит пакет с информацией, который передает Peripheral.
MTU (maximum transmission unit) такого пакета определяется в процессе подключения и варьируется от устройства к устройству и в зависимости от операционной системы. В протоколе версии 4.0 MTU был около 30, и размер полезных данных не превышал 20 байтов. В версии 4.2 всё поменялось, теперь можно передавать около 520 байтов. Но, к сожалению, эту версию протокола поддерживают только устройства младше IPhone 5s. Размер накладных расходов, независимо от размера MTU, составляет 7 байтов: сюда входят ATT и L2CAP заголовков. С записью, в целом, похожая ситуация.
Есть только два режима: с ответом и без. Режим без ответа значительно ускоряет передачу данных, поскольку нет интервала ожидания перед следующей записью. Но этот режим доступен не всегда, не на всех устройствах и не на всех системах. Доступ к этому режиму записи может ограничить сама система, потому что он считается менее энергоэкономичным. В iOS eсть метод, в котором можно проверить перед записью, доступен ли такой режим.
Теперь давайте рассмотрим, из чего состоит протокол.
Протокол состоит из 5 уровней. Слой приложения — эта ваша логика, описанная поверх CoreBluetooth. GATT (Generic Attributes Layer) служит для обмена сервисами и характеристиками, которые есть на устройствах. ATT (Attributes Layer) используется для управления вашими характеристиками и передачей ваших данных. L2CAP — низкоуровневый протокол обмена данными. Controller — это уже сам BT-чип.
Вы, наверное, спросите, что такое GATT и как мы можем с ним работать?
GATT состоит из характеристики и сервисов. Характеристика — это объект, в котором хранятся ваши данные, словно переменная. А сервис — это группа, в которой находятся ваши характеристики, словно пространство имён. У сервиса есть название — UUID, вы сами его выбираете. Сервис может содержать в себе дочерний сервис.
У характеристики тоже есть свой UUID — фактически, имя. Значение (Value) характеристики — это NSData, сюда вы можете записывать и хранить данные. Дескрипторы — это описание вашей характеристики, вы можете описать, какие данные вы ожидаете в этой характеристике, или что они означают. В протоколе Bluetooth есть много дескрипторов, но в Apple-системах пока доступно только два: человеческое описание и формат данных. Также есть уровни доступа (Permissions) для вашей характеристики:
Попробуем сами
У нас появилась идея сделать возможность передачи денег по воздуху, ничего не требуя от получателя. Представьте, вот ломаете голову над очень интересной задачей, пишете идеальный код, и тут коллега предлагает сходить за кофе. А вы так увлечены задачей, что не можете отлучиться, и просите его купить вам чашечку вкусного капучино. Он приносит вам кофе, и нужно вернуть ему деньги. Можно перевести по номеру телефона, работает отлично. Но вот неловкая ситуация — вы не знаете его номера. Ну вот так, три года работаете, а номерами не обменялись 🙂
Поэтому мы решили сделать возможность передачи денег тем, кто находится рядом, без ввода каких-либо пользовательских данных. Как в AirDrop. Просто выбрать пользователя и отправить нужную ему сумму. Давайте посмотрим, что нам для этого нужно.
Отображение PUSH
Нам нужно, чтобы отправитель:
Для начала нужно придумать названия нашего сервиса и характеристик. Как я говорил, это UUID. Просто генерируем их и сохраняем на Peripheral и Central, чтобы на обоих устройствах были одинаковые.
Далее нам нужно будет создать менеджеры: один для передачи денежных средств, другой для получения. Нужно просто указать делегатов. Передавать у нас будет Central, получать Peripheral. Мы создаем оба, потому что и отправителем, и получателем может быть одно лицо в разное время.
Теперь нам нужно сделать возможность обнаружения получателя и записать в нашу характеристику реквизиты получателя.
Для начала создадим сервис. Пропишем UUID и укажем, что он primary — то есть сервис является главным для этого устройства. Хороший пример: пульсомер, для которого главным сервисом будет текущее состояние пульса, а состояние батареи — это второстепенная информация.
Далее создаем две характеристики: одну для чтения реквизитов получателя, вторую для записи, чтобы получатель мог узнать об отправке денег. Регистрируем их в нашем сервисе, потом добавляем в менеджер, запускаем обнаружение и указываем UUID сервиса, чтобы все устройства, которые находятся рядом, могли узнать о нашем сервисе до подключения к нему. Эти данные помещаются в пакет, который отправляет Central в ходе вещания.
Получатель готов, приступим к отправителю. Запустим поиск и подключение.
При включении менеджера мы запускаем поиск устройств с нашим сервисом. При нахождении мы их получаем в методе делегата и сразу подключаемся. Важно: нужно сохранять strong-ссылку на все Peripheral, с которыми вы работаете, иначе они «утекут».
После успешного подключения настраиваем делегат, который будет работать с данным устройством, и получаем от устройства нужный нам сервис.
Мы успешно подключились к получателю, теперь нужно прочитать его реквизиты.
Мы после подключения уже запросили все сервисы с устройства. И после их получения будет вызван метод делегата, в котором будут перечислены все сервисы, доступные на данном устройстве. Находим нужный и запрашиваем его характеристики. Результат можно будет найти по UUID в методе делегата, в котором хранятся данные для перевода. Пробуем их прочитать, и получим искомое опять в методе делегата. Все сервисы, характеристики и их значения кешируются системой, так что запрашивать их впоследствии каждый раз необязательно.
Всё, мы отправили деньги за кофе, самое время показать получателю красивое уведомление, чтобы он ждал рубли на своем счёте. Для этого нужно реализовать процесс отправки сообщения.
У отправителя достаем нужную нам характеристику, в данном случае мы её взяли из сохраненного значения. Но до этого вам её нужно получить с устройства, как мы делали до этого. А дальше просто записываете данные в нужную характеристику.
После этого на другом устройстве получаем в методе делегата запрос на запись. Тут вы можете прочитать данные, которые вам отправляют, ответить на какую-либо ошибкой, например, нет доступа, или данной характеристики не существует. Всё будет работать, но только если оба устройства включены и приложения активны. А нам нужно, чтобы работало и в фоне!
Apple позволяет использовать Bluetooth в фоне. Для этого нужно в info.plist указать ключ, в каком режиме мы хотим использовать, в Peripheral или Central.
Далее в менеджере нужно указать ключ восстановления и создать метод делегата. Теперь нам доступен и фоновый режим. Если приложение заснёт или будет выгружено из памяти, то при нахождении нужного Peripheral или при подключении Central оно проснётся, а менеджер восстановится с вашим ключом.
Всё отлично, уже готовы релизиться. Но тут к нам прибегают дизайнеры и говорят: «Хотим вставить фотографии пользователей, чтобы им было легче находить друг друга». Что же делать? У нас в характеристику можно записать всего какие-то 500 байтов, а на каких-то устройствах вообще 20 🙁
Спустимся глубже
Чтобы решить эту проблему, нам пришлось спуститься глубже.
Сейчас мы общались устройствами на уровне GATT/ATT. Но в iOS 11 у нас есть доступ к протоколу L2CAP. Однако в этом случае придётся самостоятельно позаботиться о передаче данных. Пакеты отправляются с MTU 2 Кб, не нужно ни во что перекодировать, применяется обычный NSStream. Скорость передачи данных до 394 Килобит/с., по заверению Apple.
Допустим, вы передаёте какие-либо данные вашего сервиса от Peripheral к Central в виде обычных характеристик. И понадобилось открыть канал. Вы открываете его на Peripheral, в ответ получаете PSM — это номер канала, к которому можно подключиться, и нужно с помощью тех же характеристик передать его Central. Номер динамический, система сама выбирает, какой PSM открыть в данный момент. После передачи можно уже на Сentral подключиться к Peripheral и обмениваться данными в удобном для вас формате. Давайте рассмотрим, как это сделать.
Для начала на Peripheral открываем порт с шифрованием. Можно делать и без шифрования, тогда это немного ускорит передачу.
Далее мы в методе делегата получаем PSM и отправляем на другое устройство.
После подключения другого устройства у нас вызовется метод, в котором из канала мы можем достать нужные нам для передачи NSStream.
С Central еще проще, мы просто подключаемся к каналу с нужным номером…
… и после этого получаем нужные нам стримы. В них вы можете передавать абсолютно любые данные любого размера, и строить поверх L2CAP свой протокол. Так мы и реализовали у себя передачу фотографий получателя.
Но есть подводные камни, куда же без них.
Подводные камни
Давайте рассмотрим подводные камни при работе в фоновом режиме. Поскольку вам доступны роли Peripheral и Central, вы можете подумать. что в фоне можете определять, какие устройства рядом находятся в фоновом режиме, а какие в активном. В теории так и должно было быть, но Apple ввела ограничение: телефоны, которые находятся в фоновом режиме, будь то Central или Peripheral, не доступны для других телефонов, которые тоже находятся в фоновом режиме. Также телефоны, которые находятся в фоновом режиме, не видны с неiOS-устройств. Давайте рассмотрим почему так происходит.
Когда ваше устройство активно, оно посылает обычный broadcast-пакет, в котором может быть имя устройства и список сервисов. которые предоставляет это устройство. И overflow данные — всё что не поместилось.
Когда же устройство переходит в фоновый режим, оно не передает название, а список поддерживаемых сервисов переносит в overflow-данные. Если приложение активно, то при сканировании с iOS-устройства оно читает эти данные, а при переходе в фон — игнорирует. Поэтому при переходе в фон вы не сможете видеть приложения, которые также находятся в фоне. Остальные операционные системы Apple всегда игнорируют overflow-данные, поэтому если вы будете искать устройства, поддерживающие ваш сервис, то получите пустой массив. А если подключиться к каждому устройству, которое находится рядом, и запросить поддерживаемые сервисы, то в списке, возможно, будет ваш сервис, и вы сможете с ним работать.
Дальше мы уже готовились передавать в тестирование, правили мелкие недочёты, занимались оптимизацией. И вдруг в какой-то момент мы стали получать в консоли эту ошибку:
Самое плохое было в том, что никакой метод делегата не вызывался, мы даже не могли никак обыграть эту ошибку для пользователя. Просто сообщение в лог — и тишина, всё замирало. Никаких особых изменений не вносилось, поэтому мы начали откатываться по коммитам. И обнаружили, что однажды оптимизировали код и переделали способ записи данных. Проблема крылась в том, что не все клиенты были обновлены, поэтому возникала такая ошибка.
Мы, счастливые, что всё исправили, побежали скорее передавать в тестирование, а они нам почти сразу возвращают: «Ваши модные фоточки не работают. Они все недогруженные приходят». Мы начали пробовать, и правда, иногда, на разных устройствах, в разное время приходят битые фотографии. Начали искать причину.
И тут снова увидели прежнюю ошибку. Сразу подумали, что дело в разных версиях. Но после полного удаления старой версии со всех тестовых устройств ошибка всё равно воспроизводилась. Мы взгрустнули…
Начали искать инструмент для отладки. Первое, что нам попалось, это Apple Bluetooth Explorer. Мощная программа, много всего умеет, но вот для отладки протокола Bluetooth LE одна маленькая вкладка с поиском устройств и получением характеристик. А нам-то нужно было анализировать L2CAP.
Потом нашли LightBlue Explorer. Оказалась вполне приличная программа, правда, с дизайном из iOS 7. Может делать то же самое, что и Bluetooth Explorer, а еще умеет подписываться на характеристики. И работает стабильнее. Всё хорошо, но опять без L2CAP.
И тут нам вспомнился всем известный сниффер WireShark.
Оказалось, он знаком с Bluetooth LE: может читать L2CAP, но только под Windows. Хотя это не страшно, что мы, не найдем винду, что ли. Самый большой минус — программа работает только с определенным устройством. То есть нужно было найти где-то устройство в официальном магазине. А вы сами понимаете, в большой компании вряд ли одобрят покупку непонятного устройства на барахолке. Мы даже начали просматривать зарубежные онлайн-магазины.
Но тут обнаружили в Additional Xcode Tools программу PacketLogger. Она позволяет смотреть траффик, которой идет на OS X-устройстве. А почему бы не переписать наш MoneyDrop под OS X? Он у нас уже был отдельной библиотеки. Мы просто заменили UIImage на NSImage, всё завелось само через 10 минут.
Наконец-то мы могли читать пакеты, которыми обмениваются устройства. Сразу стало понятно, что в момент передачи данных по L2CAP записывалась одна из характеристик. А из-за того, что канал был полностью занят передачей фотографии, iOS игнорировала запись, а отправитель после игнора обрывал канал. После исправления проблем с передачей фотографии не было.
На этом всё, спасибо за прочтение 🙂

















