Error 133 0x85 gatt error

Hi, I am running ble_app_blinky example on nRF5280 custom board, it is giving me Error 133 (0x85): GATT ERROR . Since I have nrf52DK, I tried same example with

Hi,

I am running ble_app_blinky example on nRF5280 custom board, it is giving me Error 133 (0x85): GATT ERROR. Since I have nrf52DK, I tried same example with SD 132 on nrf52832 it works as expected.

I went through devzone and there are many questions with similar issues but  couldn’t find a solution.

Could you please let me know what could be reason for the same?

https://devzone.nordicsemi.com/f/nordic-q-a/32590/error-133-0x85-gatt-error-with-htc-u11-life

https://devzone.nordicsemi.com/f/nordic-q-a/33313/android-gatt-133-error

SDK 15.2.0

SD 140

nRF52840

Keil

Tried on Honor 7X (Android 8.0.0), Redmi Note 4 (Android 7.0),

nRF Connect, 2019-04-24
Nordic_Blinky (XX:XX:XX:XX:XX:XX)
V 16:07:10.488 Connecting to XX:XX:XX:XX:XX:XX...
D 16:07:10.488 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)
D 16:07:19.253 [Callback] Connection state changed with status: 133 and new state: DISCONNECTED (0)
E 16:07:19.253 Error 133 (0x85): GATT ERROR
I 16:07:19.253 Disconnected
D 16:07:21.850 gatt.close()
D 16:07:21.854 wait(200)
V 16:07:22.056 Connecting to XX:XX:XX:XX:XX:XX...
D 16:07:22.057 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)
D 16:07:52.111 [Callback] Connection state changed with status: 133 and new state: DISCONNECTED (0)
E 16:07:52.111 Error 133 (0x85): GATT ERROR
I 16:07:52.111 Disconnected
D 16:07:54.117 gatt.close()
D 16:07:54.120 wait(200)
V 16:07:54.321 Connecting to XX:XX:XX:XX:XX:XX...
D 16:07:54.322 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)
D 16:08:09.849 [Callback] Connection state changed with status: 133 and new state: DISCONNECTED (0)
E 16:08:09.850 Error 133 (0x85): GATT ERROR
I 16:08:09.850 Disconnected
D 16:08:14.775 gatt.close()
D 16:08:14.779 wait(200)
V 16:08:14.982 Connecting to XX:XX:XX:XX:XX:XX...
D 16:08:14.982 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)
D 16:08:15.541 [Callback] Connection state changed with status: 133 and new state: DISCONNECTED (0)
E 16:08:15.541 Error 133 (0x85): GATT ERROR
I 16:08:15.541 Disconnected
00> <info> app: Template example started.
00> <info> app: Fast advertising.
00> <info> app: Connected.
00> <info> app: Fast advertising.
00> <info> app: Disconnected.

Время прочтения
13 мин

Просмотры 13K

Часть 2
Часть 2

Содержание

Часть #1 (scanning).

Часть #2 (connecting/disconnecting), вы здесь.

Часть #3 (read/write)

Часть #4 (bonding)

В предыдущей статье мы подробно рассмотрели сканирование устройств. Эта статья — о подключенииотключении и обнаружении сервисов (discovering services).

Подключение к устройству

После удачного сканирования, вы должны подключиться к устройству, вызывая метод connectGatt(). В результате мы получаем объект – BluetoothGatt, который будет использоваться для всех GATT операций, такие как чтение и запись характеристик. Однако будьте внимательны, есть две версии метода connectGatt(). Поздние версии Android имеют еще несколько вариантов, но нам нужна совместимость с Android-6 поэтому мы рассматриваем только эти две:

BluetoothGatt connectGatt(Context context, boolean autoConnect,
        BluetoothGattCallback callback)
BluetoothGatt connectGatt(Context context, boolean autoConnect,
        BluetoothGattCallback callback, int transport)

Внутренняя реализация первой версии – это фактически вызов второй версии с аргументом transport = TRANSPORT_AUTO. Для подключения BLE устройств такой вариант не подходит. TRANSPORT_AUTO используется для устройств с поддержкой и BLE и классического Bluetooth протоколов. Это значит, что Android будет сам выбирать протокол подключения. Этот момент практически нигде не описан и может привести к непредсказуемым результатам, много людей сталкивались с такой проблемой. Вот почему вы должны использовать вторую версию connectGatt() с transport = TRANSPORT_LE:

BluetoothGatt gatt = device.connectGatt(context, false, 
    bluetoothGattCallback, TRANSPORT_LE);

Первый аргумент – context приложения. Второй аргумент – флаг autoconnect, говорит подключаться немедленно (false) или нет (true). При немедленном подключении (false) Android будет пытаться соединиться в течение 30 секунд (на большинстве смартфонов), по истечении этого времени придет статус соединения status_code = 133. Это не официальная ошибка для таймаута соединения. В исходниках Android код фигурирует как GATT_ERROR. К сожалению, эта ошибка появляется и в других случаях. Имейте ввиду, с autoconnect = falseAndroid делает соединение только с одним устройством в одно и то же время (это значит если у вас несколько устройств — подключайте их последовательно, а не паралелльно). Третий аргумент – функция обратного вызова BluetoothGattCallback (callback) для конкретного устройства. Этот колбек используется для всех связанных с устройством операциях, такие как чтение и запись. Мы рассмотрим это более детально в следующей статье.

Autoconnect = true

Если вы установите autoconnect = true, Android будет подключаться самостоятельно к устройству всякий раз, когда оно будет обнаружено. Внутри это работает так: Bluetooth стек сканирует сохраненные устройства и когда увидит одно из них – подключается к нему. Это довольно удобно, если вы хотите подключиться к конкретному устройству, когда оно становится доступным. Фактически, это предпочтительный способ для переподключения. Вы просто создаете BluetoothDevice объект и вызываете connectGatt с autoconnect = true.

BluetoothDevice device = 
bluetoothAdapter.getRemoteDevice("12:34:56:AA:BB:CC");

BluetoothGatt gatt = 
device.connectGatt(context, true, bluetoothGattCallback, TRANSPORT_LE);

Обратите внимание, этот подход работает только, если устройство есть в Bluetooth кеше или устройство было уже сопряжено (bonding). Посмотрите мою предыдущую статью, где подробно объясняется работа с Bluetooth кешем. При перезагрузке смартфона или выключении/включении Bluetooth (а также Airplane режима) – кеш очистится, это надо проверять перед подключением с autoconnect = true, что действительно раздражает.

Autoconnect работает только с закешированными и сопряженными (bonded) устройствами!

Для того, чтобы узнать, закешировано устройство или нет, можно использовать небольшой трюк. После создания объекта BluetoothDevice, вызовите у него getType, если результат – TYPE_UNKNOWN, значит устройство не закешировано. В этом случае, необходимо просканировать устройство с этим мак-адресом (используя не агрессивный метод сканирования) и после этого можно использовать автоподключение снова.

Android-6 и ниже имеет известный баг, в котором возникает гонка состояний и автоматическое подключение становится обычным (autoconnect = false). К счастью, умные ребята из Polidea нашли решение для этого. Настоятельно рекомендуется использовать его, если думаете использовать автоподключение.

Преимущества:

  • работает достаточно хорошо на современных версиях Android (прим. переводчика — от Android-8 и выше).

  • возможность подключаться к нескольким устройствам одновременно;

Недостатки:

  • работает медленнее, если сравнивать сканирование в агрессивном режиме + подключение с autoconnect = false. Потому что Android в этом случае сканирует в режиме SCAN_MODE_LOW_POWER, экономя энергию.

Изменения статуса подключения

После вызова connectGatt(), Bluetooth стек присылает результат в колбек onConnectionStateChange, он вызывается при любом изменении соединения.

Работа с этим колбеком – достаточно нетривиальная вещь. Большинство простых примеров из сети выглядит так (не обольщайтесь):

public void onConnectionStateChange(final BluetoothGatt gatt, 
                                    final int status, 
                                    final int newState) {
    if (newState == BluetoothProfile.STATE_CONNECTED) {
        gatt.discoverServices();
    } else {
        gatt.close();
    }
}

Этот код обрабатывает только аргумент newState и полностью игнорирует status. В многих случаях это работает и кажется безошибочным. Действительно, после подключения, следующее что нужно сделать – это вызвать discoverServices(). А в случае отключения — необходимо сделать вызов close(), чтобы Android освободил все связанные ресурсы в стеке Bluetooth. Эти два момента очень важные для стабильной работы BLE под Android, давайте их обсудим прямо сейчас!

При вызове connectGatt(), Bluetooth стек регистрирует внутри себя интерфейс для нового клиента (client interface: clientIf).

Возможно вы заметили такие логи в LogCat:

D/BluetoothGatt: connect() - device: B0:49:5F:01:20:XX, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() — UUID=0e47c0cf-ef13–4afb-9f54–8cf3e9e808d5
D/BluetoothGatt: onClientRegistered() — status=0 clientIf=6

Здесь видно, что клиент 6 был зарегистрирован после вызова connectGatt(). Максимальное количество клиентов (подключения) у Android равно 30 (константа GATT_MAX_APPS в исходниках), при достижении которого – Android не будет подключаться к устройствам вообще и вы будете получать постоянно ошибку подключения. Достаточно странно, но сразу после загрузки Android уже имеет 5 или 6 таких подключенных клиентов, предполагаю, что Android использует их для внутренних нужд. Таким образом, если вы не вызываете метод close(), то счетчик клиентов увеличивается каждый раз при вызове connectGatt(). Когда вы вызываете close(), Bluetooth стек удаляет ваш колбек, счетчик клиентов уменьшается на единицу и освобождает ресурсы клиента.

D/BluetoothGatt: close()
D/BluetoothGatt: unregisterApp() — mClientIf=6

Важно всегда вызывать close() после отключения! А сейчас обсудим основные случаи дисконнекта устройств.

Состояние подключения (newState)

Переменная newState содержит новое состояние подключения и может иметь 4 значения:

  • STATE_CONNECTED

  • STATE_DISCONNECTED

  • STATE_CONNECTING

  • STATE_DISCONNECTING

Значения говорят сами за себя. Хотя состояния STATE_CONNECTINGSTATE_DISCONNECTING есть в документации, на практике я их не встречал. Так что, в принципе, можно не обрабатывать их, но для уверенности, я предлагаю их явно учитывать (прим. переводчика — и это лучше, чем не обрабатывать их), вызывая close() только в том случае если устройство действительно отключено.

Статус подключения (status)

В примере выше, переменная статуса status полностью игнорировалась, но в действительности обрабатывать ее важно. Эта переменная, по сути, является кодом ошибки. Вы можете получить GATT_SUCCESS в результате как подключения, так и контролируемого отключения. Таким образом, мы можем по-разному обрабатывать контролируемое или внезапное отключение устройства. Если вы получили значение отличное от GATT_SUCCESS, значит «что-то пошло не так» и в status будет указана причина. К сожалению, объект BluetoothGatt дает очень мало кодов ошибок, все они описаны здесь. Чаще всего вы будете встречаться с кодом 133 (GATT_ERROR). Который не имеет точного описания, и просто говорит – «произошла какая-то ошибка». Не очень информативно, подробнее об GATT_ERROR позже.

Теперь мы знаем, что обозначают переменные newState и status, давайте улучшим наш колбек onConnectionStateChange:

public void onConnectionStateChange(final BluetoothGatt gatt, 
                                    final int status, 
                                    final int newState) {
if(status == GATT_SUCCESS) {
    if (newState == BluetoothProfile.STATE_CONNECTED) {
        // Мы подключились, можно запускать обнаружение сервисов
        gatt.discoverServices();
    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
        // Мы успешно отключились (контролируемое отключение)
        gatt.close();
    } else {
        // мы или подключаемся или отключаемся, просто игнорируем эти статусы
    }
} else {
   // Произошла ошибка... разбираемся, что случилось!
   ...
   gatt.close();
} 

Это не последний вариант, мы еще улучшим колбек в этой статье. В любом случае, теперь у нас есть обработка ошибок и успешных операций.

Состояние bonding (bondState)

Последний параметр, который необходимо учитывать в колбеке onConnectionStateChange – это bondState, состояние сопряжения (bonding) с устройством. Мы получаем этот параметр так:

int bondstate = device.getBondState();

Состояние bonding может иметь одно из трех значений BOND_NONEBOND_BONDING or BOND_BONDED. Каждое из них влияет на то, как обрабатывать подключение.

  • BOND_NONE, нет проблем, можно вызывать discoverServices();

  • BOND_BONDING, устройство в процессе сопряжения, нельзя вызывать discoverServices(), так как Bluetooth стек в работе и запуск discoverServices()может прервать сопряжение и вызвать ошибку соединения. discoverServices()вызываем только после того, как пройдет сопряжение (bonding);

  • BOND_BONDED, для Android-8 и выше, можно запускать discoverServices() без задержки. Для версий 7 и ниже может потребоваться задержка перед вызовом. Если ваше устройство имеет Service Changed Characteristic, то Bluetooth стек в этот момент еще обрабатывает их и запуск discoverServices() без задержки может вызвать ошибку соединения. Добавьте 1000-1500мс задержки, конкретное значение зависит от количества характеристик на устройстве. Используйте задержку всегда, если вы не знаете сколько Service Changed Characteristic имеет устройство.

Теперь мы можем учитывать состояние bondState вместе с status и newState:

if (status == GATT_SUCCESS) {
    if (newState == BluetoothProfile.STATE_CONNECTED) {
        int bondstate = device.getBondState();
        // Обрабатываем bondState
        if(bondstate == BOND_NONE || bondstate == BOND_BONDED) {
            // Подключились к устройству, вызываем discoverServices с задержкой
            int delayWhenBonded = 0;
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
                delayWhenBonded = 1000;
            }
            final int delay = bondstate == BOND_BONDED ? delayWhenBonded : 0;
            discoverServicesRunnable = new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, String.format(Locale.ENGLISH, "discovering services of '%s' with delay of %d ms", getName(), delay));
                    boolean result = gatt.discoverServices();
                    if (!result) {
                        Log.e(TAG, "discoverServices failed to start");
                    }
                    discoverServicesRunnable = null;
                }
            };
            bleHandler.postDelayed(discoverServicesRunnable, delay);
        } else if (bondstate == BOND_BONDING) {
            // Bonding в процессе, ждем когда закончится
            Log.i(TAG, "waiting for bonding to complete");
        }
....

Обработка ошибок

После того как мы разобрались с успешными операциями, давайте взглянем на ошибки. Есть ряд ситуаций, которые на самом деле «нормальные», но выдают себя за ошибки.

  • Устройство отключилось намеренно. Например, все данные были переданы и больше ему нечего делать. Вы получите статус — 19 (GATT_CONN_TERMINATE_PEER_USER);

  • Истекло время ожидания соединения и устройство отключилось само. В этом случае придет статус — 8 (GATT_CONN_TIMEOUT);

  • Низкоуровневая ошибка соединения, которая привела к отключению. Обычно это статус — 133 (GATT_ERROR) или более конкретный код, если повезет;

  • Bluetooth стек не смог подключится ни разу. Здесь также получим статус — 133 (GATT_ERROR);

  • Соединение было потеряно в процессе bonding или discoverServices. Необходимо выяснить причину и возможно повторить попытку подключения.

Первые два случая абсолютно нормальные явления и все что нужно сделать — это вызывать close() и подчистить ссылки на объект BluetoothGatt, если необходимо. В остальных случаях, либо ваш код, либо устройство, что-то делает не так. Вы возможно захотите уведомить UI или другие части приложения о проблеме, повторить подключение или еще каким-то образом отреагировать на ситуацию. Взгляните как я сделал это в моей библиотеке.

Статус 133 при подключении (connecting)

Статус — 133 часто встречается при попытках подключиться к устройству, особенно во время разработки. Этот статус может иметь множество причин, некоторые из них можно контролировать:

  • Убедитесь, что вы всегда вызываете close() при отключении. Если этого не сделать, в следующий раз при подключении вы точно получите status=133;

  • Всегда используйте TRANSPORT_LE в вызове connectGatt();

  • Перезагрузите смартфон. Возможно Bluetooth стек выбрал лимит по клиентским подключениям или есть внутренняя проблема. (Прим. переводчика: я сначала выключал/включал Bluetooth, потом Airplane режим и если не помогало — перезагружал);

  • Проверьте что устройство посылает advertising пакеты. Вызов connectGatt() с autoconnect = false имеет таймаут 30 секунд, после чего присылает ошибку status=133;

  • Замените/зарядите батарею на устройстве. Обычно устройства работают нестабильно при низком заряде;

Если вы попробовали все способы выше и все еще получаете статус 133, необходимо просто повторить подключение! Это одна из Android ошибок, которую мне так и не удалось понять или решить. Иногда вы получаете 133 при подключении к устройству, но если вызывать close() и переподключиться, то все работает без проблем! Есть подозрение, что проблема в кеше Android и вызов close() сбрасывает его состояние для конкретного устройства. Если кто-нибудь поймет, как решить эту проблему – дайте мне знать!

Отключение по запросу (disconnect)

Для отключения устройства вам необходимо сделать шаги:

  • вызвать disconnect();

  • подождать обновления статуса в onConnectionStateChange;

  • вызвать close();

  • освободить связанные с объектом gatt ресурсы;

Команда disconnect() фактически разрывает соединение с устройством и обновляет внутреннее состояние Bluetooth стека. Затем вызывается колбек onConnectionStateChange с новым состоянием «disconnected».

Вызов close() удаляет ваш  BluetoothGattCallback и освобождает клиента в Bluetooth стеке.

Наконец, удаление BluetoothGatt освободит все связанные с подключением ресурсы.

Отключение «неправильно»

В примерах из сети можно увидеть, разные примеры отключения, например:

  • вызвать disconnect()

  • сразу вызвать close()

Это будет работать более-менее. Да устройство отключится, но вы никогда не получите вызов колбека с состоянием «disconnected». Дело в том, что disconnect() операция асинхронная (не блокирует поток и имеет свое время выполнения), а close() немедленно удаляет коллбек! Получается, когда Android будет готов вызвать колбек, его уже не будет.

Иногда в примерах не вызывают disconnect(), а только close(). Это приведет к отключению устройства, но это неправильный способ, поскольку disconnect() отключает активное соединение и отменяет ожидающее автоматическое подключение (вызов с autoconnect = true). Поэтому, если вы вызываете только close(), любое ожидающее автоподключение может привести к новому подключению.

Отмена попытки подключения

Если вы хотите отменить подключение после connectGatt(), вам нужно вызвать disconnect(). Так как в этому моменту вы еще не подключены, колбек onConnectionStateChange не сработает! Просто подождите некоторое время после disconnect() и после этого вызывайте close() (прим. переводчика: обычно это 50-100мс).

При удачной отмене вы увидите примерно такое в логах:

D/BluetoothGatt: cancelOpen() — device: CF:A9:BA:D9:62:9E

Скорее всего, вы никогда не отмените соединение, для параметра autoconnect = false. Часто это делается для подключений с autoconnect = true. Например, когда приложение на переднем плане – вы подключаетесь к вашим устройствам и отключаетесь от них, если приложение переходит в фон.

Прим. переводчика: но это не значит что для autoconnect = false не надо проводить такую отмену!

Обнаружение сервисов (discovering services)

Как только вы подключились к устройству, необходимо запустить обнаружение его сервисов вызовом discoverServices(). Bluetooth стек запустит серию низкоуровневых команд для получения сервисовхарактеристик и дескрипторов. Это занимает обычно около одной секунды в зависимости от того сколько таких служб, характеристик, дескрипторов имеет ваше устройство. В результате будет вызыван колбек onServicesDiscovered.

Первым делом проверим, есть ли какие ошибки после обнаружения сервисов:

// Проверяем есть ли ошибки? Если да - отключаемся
if (status == GATT_INTERNAL_ERROR) {
    Log.e(TAG, "Service discovery failed");
    disconnect();
    return;
}

Если есть ошибки (обычно это GATT_INTERNAL_ERROR со значением 129), делаем отключение устройства, что-то исправить здесь невозможно (нет специальных технических способов для этого). Вы просто отключаете устройство и повторно пробуете подключиться.

Если все прошло удачно, вы получите список сервисов:

final List<BluetoothGattService> services = gatt.getServices();
Log.i(TAG, String.format(Locale.ENGLISH,"discovered %d services for '%s'", services.size(), getName()));
// Работа со списком сервисов (если требуется)
...

Кеширование сервисов.

Bluetooth стек кеширует найденные на устройстве сервисы, характеристики и дескрипторы. Первое подключение вызывает реальное обнаружение сервисов, все последующие – возвращаются кешированные версии. Это соответствует стандарту Bluetooth. Обычно это нормально и сокращает время соединения с устройством. Однако в некоторых случаях, может потребоваться очистить кеш, чтобы снова обнаружить их с устройства при следующем соединении. Типичный сценарий: обновление прошивки, в которой изменяется набор сервисов, характеристик, дескрипторов. Есть скрытый метод очистки кеша и добраться до него нам поможет механизм рефлексии Java:

private boolean clearServicesCache() {
    boolean result = false;
    try {
        Method refreshMethod = bluetoothGatt.getClass().getMethod("refresh");
        if(refreshMethod != null) {
            result = (boolean) refreshMethod.invoke(bluetoothGatt);
        }
    } catch (Exception e) {
        Log.e(TAG, "ERROR: Could not invoke refresh method");
    }
    return result;
}

Этот метод асинхронный, дайте ему некоторое время для завершения!

Странные штуки в подключении/отключении

Хотя операции подключения и отключения выглядят просто, есть некоторые особенности, которые нужно знать.

  • Случайная ошибка 133 при подключении, выше мы разобрались как с ней работать;

  • Периодическое зависание подключения, не срабатывает таймаут и не вызывается колбек onConnectionStateChange. Это случается не часто, но я видел такие случае при низком уровне батареи или когда устройство находится на границе доступности по расстоянию Bluetooth. Скорее всего общение с устройством происходит, но затем прерывается и зависает. Мой обходной путь – использовать свой таймер подключения и в случае таймаута – закрывать соединение и отключаться;

  • Некоторые смартфоны имеют проблему с подключением во время сканирования. Например, Huawei P8 Lite один из таких. Останавливаем сканнер перед любым подключением (Прим. переводчика: это правило соблюдаем строго!);

  • Все вызовы подключения/отключения асинхронные. То есть неблокирующие, но при этом им нужно время, чтобы выполнится до конца. Избегайте быстрый запуск их друг за другом (Прим. переводчика: я обычно использую задержку 50-100мс между вызовами).

Следующая статья: чтение и запись характеристик.

Теперь мы разобрались с подключением/отключением и обнаружением сервисов, следующая статья – о том, как работать с характеристиками.

Не терпится поработать с BLE? Попробуйте мою библиотеку Blessed for Android. Она использует все подходы из этой серии статей и упрощает работу с BLE в вашем приложении.

Hey @philips77, sorry to revive this thread, but perhaps you have some insight on how to get around some similar 129 and 133 issues I’m having when trying to DFU?

We’re using the maven release of the library, no.nordicsemi.android:dfu:0.6.

Things work fine on our newer bootloaders, where DFU runs on a different MAC address than the normal application. But we still have some old hardware in the wild that we’d like to be able to update, which reuses the same MAC address for the application and the DFU service. Even then it works fine on certain phones, such as Moto E, but it only works about 10% of the time on other phones, such as Galaxy S5. On such phones, the other 90% of the time, the DFU library hits the following errors:

…
E/DfuBaseService: Service discovery error: 129
E/DfuBaseService: An error occurred while connecting to the device:16513
D/BluetoothGatt: cancelOpen() - device: FA:B0:BE:04:6C:7E
D/BluetoothGatt: onClientConnectionState() - status=133 clientIf=7 device=FA:B0:BE:04:6C:7E
E/DfuBaseService: Connection state change error: 133 newState: 0
…

The full log output is attached here.

In that log you’ll also see a few random things we try before starting DFU, with 1 second delays between each step:

  • «old DFU step 1» is refreshing the service cache, using the hidden «refresh» method on the BluetoothGatt object
  • «old DFU step 2» is calling discoverServices() on the BluetoothGatt
  • «old DFU step 3» is refreshing the service cache again
  • «old DFU step 4» is closing the BluetoothGatt
  • «old DFU step 5» is finally starting your DFU library

So anyway, if you happen to have any thoughts on what might be going wrong or how we might be able to fix it, that would be excellent!

Я новичок в Android и теперь делаю простое приложение, которое требует записи некоторых данных в периферийное устройство.

на самом деле ничего не происходит в устройстве Samsung GT-S7272C. Но когда я переключаюсь на Sony LT29i, всегда будет статус 133, когда я пытаюсь записать определенную характеристику. Я дам вам краткий код.

BluetoothGattService syncService = gatt.getService(SYNC_DATA_SERVICE);
BluetoothGattCharacteristic tChar = syncService.getCharacteristic(SYNC_TIME_INPUT_CHAR);
if (tChar == null) throw new AssertionError("characteristic null when sync time!");

int diff = /*a int*/;
tChar.setValue(diff, BluetoothGattCharacteristic.FORMAT_SINT32, 0);
gatt.writeCharacteristic(tChar);

и функция onCharacteristicWrite:

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    Log.d(TAG, String.format("Sync: onCharWrite, status = %d", status));
    try {
        if (status != BluetoothGatt.GATT_SUCCESS) throw new AssertionError("Error on char write");
        super.onCharacteristicWrite(gatt, characteristic, status);
        if (characteristic.getUuid().equals(SYNC_TIME_INPUT_CHAR)) {
            BluetoothGattService syncService = gatt.getService(SYNC_DATA_SERVICE);
            BluetoothGattCharacteristic tChar = syncService.getCharacteristic(SYNC_HEIGHT_INPUT_CHAR);
            if (tChar == null) throw new AssertionError("characteristic null when sync time!");
            tChar.setValue(/*another int*/, BluetoothGattCharacteristic.FORMAT_SINT32, 0);
            gatt.writeCharacteristic(tChar);
        }
        else if {
            ...
        }
    } catch (AssertionError e) {
        ...
    }

запись в первую характеристику ничего не имеет неправильно и управление достигнет onCharacteristicWrite и введите первый if заявление со статусом 0, что означает успех. Проблема заключается во втором действии записи в if оператор, который также вызовет функцию onCharacteristicWrite, но даст статус 133, который не может быть найден в официальный сайт. Затем устройство автоматически отключается.

я подтвердил, что тип данных и смещение все правильно. И потому, что в другом устройство это работает очень хорошо, я думаю, что могут быть некоторые крошечные различия реализации стека bluetooth между различными устройствами, что я должен сделать что-то более сложное, чтобы решить эту проблему.

я долго искал результат. Некоторые результаты приводят меня к исходному коду C (Извините, я опубликую ссылку ниже, потому что у меня недостаточно репутации для публикации более 2 ссылок), но я могу найти только это 133 означает GATT_ERROR там, что не более полезно, чем просто 133. Я также нашел проблему в группе google, обсуждая некоторые знакомые вопросы, но я не смог найти решение здесь.

мне немного грустно, потому что, если что-то не так с кодом C, даже если я могу найти, что не так, у меня все равно нет способа сделать это правильно в моем собственном коде, верно?

Я надеюсь, что у кого-то есть знакомый опыт и может дать мне некоторые предложения. Большое спасибо!

ссылки:

  • C исходный код:https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-4.4.2_r1/stack/include/gatt_api.h

  • вопрос: https://code.google.com/p/android/issues/detail?id=58381

4 ответов


у меня была аналогичная проблема, когда я пытался написать какую-то характеристику, которую я не могу вспомнить, хотя, если я получил тот же код ошибки или нет. (и он работал на некоторых устройствах, а не на других).

как оказалось проблема property на characteristics и writeType.

потому что характеристики могут иметь определенные значения:

  • write without response или
  • write with response

в связи с этим свойство вы должны установить writeType перед записью фактических данных в характеристику.

вы можете установить тип, как только вы получите характеристику, но прежде чем писать на нее.

BluetoothGattCharacteristic tChar = syncService.getCharacteristic(SYNC_HEIGHT_INPUT_CHAR);
        if (tChar == null) throw new AssertionError("characteristic null when sync time!");

        // use one of them in regards of the Characteristic's property
        tChar.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
        //tChar.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);


        tChar.setValue(/*another int*/, BluetoothGattCharacteristic.FORMAT_SINT32, 0);
        gatt.writeCharacteristic(tChar);

здесь код состояния ошибки / успеха и значение

GATT_ILLEGAL_PARAMETER 0x0087 (135)

GATT_NO_RESOURCES 0x0080 (128)

GATT_INTERNAL_ERROR 0x0081 (129)

GATT_WRONG_STATE 0x0082 (130)

GATT_DB_FULL 0x0083 (131)

GATT_BUSY 0x0084 (132)

GATT_ERROR 0x0085 (133)

GATT_CMD_STARTED 0x0086 (134)

GATT_PENDING 0x0088 (136)

GATT_AUTH_FAIL 0x0089 (137)

GATT_MORE 0x008a (138)

GATT_INVALID_CFG 0x008b (139)

GATT_SERVICE_STARTED 0x008c (140)

GATT_ENCRYPED_MITM GATT_SUCCESS

GATT_ENCRYPED_NO_MITM 0x008d (141)

GATT_NOT_ENCRYPTED 0x008e (142)

надеюсь, что это помогает.
Ура Голосуйте


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

из этого я заключаю, что status = 133 кажется каким-то без документов общая причина ошибки.


в моем случае мне нужно было повторно использовать активное соединение Gatt в новой деятельности, но не смог и постоянно отключался с ошибкой 133.
Итак, я прибегнул к призыву BluetoothGatt.close() до startActivity(), и (re)подключение в onStart().
Если у кого-то есть лучшая идея о том, как сохранить соединение, пожалуйста, напишите.


For the record, this article is only for those who have some background in Bluetooth development.

Android BLE development is a big pit, with very unstable connections. When a peripheral is connected multiple times, a connection failure occurs. Observation of the log shows that the onClientConnectionState() method frequently has an error code of 133.

1. Why does the error code 133 appear

  • Gatt.close () was not called and the resource was not freed, causing the connection to fail
  • Frequent attempts to establish connections
  • The system has a limit on the maximum number of Ble connections. Generally, the maximum number of Ble connections is 6. If this limit is exceeded, an error code 133 will appear
  • The BLE hardware module is faulty

How to solve it?

2. GATT Closes resources before each connection

// Gatt private BluetoothGatt mGatt; Private void connect(BluetoothDevice device, BluetoothGattCallback callback) {BluetoothGattCallback (); if (SdkUtil.isAtLeastM_23()) { mGatt = device.connectGatt(ViotSDK.getInstance().getBaseContext(), false, callback, BluetoothDevice.TRANSPORT_LE); } else { mGatt = device.connectGatt(ViotSDK.getInstance().getBaseContext(), false, callback); }} public void close() {if (mGatt! = null) { mGatt.disconnect(); mGatt.close(); mGatt = null; }}Copy the code

3. If error code 133 is displayed, configure a retry policy

In the Gatt connection callback, if the connection fails and the error code is 133, retry the connection

Private static int GATT_CONNECT_RETRY_MAX_COUNT = 3; private static int GATT_CONNECT_RETRY_MAX_COUNT = 3; private int retryCount = 0; private class BleCallback extends BluetoothGattCallback { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); If (bluetoothgatt.gatt_success == status) {// Gatt connection successful} else {// Gatt connection failed // Connection failed Need to release resources close(); If (status == 133  retryCount  GATT_CONNECT_RETRY_MAX_COUNT) {// 133 Error code Retry connect(deviice, callback); }}}}Copy the code

Since the device Rom is customized by the company system group, the operation of bluetooth switch is authorized. We can restart the device bluetooth during the retry process to release the Bluetooth connection more thoroughly.

Private static int GATT_CONNECT_RETRY_MAX_COUNT = 3; private static int GATT_CONNECT_RETRY_MAX_COUNT = 3; prvate int retryCount = 0; private Handler handler = new Handler(Looper.myLooper()); private class BleCallback extends BluetoothGattCallback { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); If (bluetoothgatt.gatt_success == status) {// gatt connection successful} else {// Gatt connection failed // release resources close(); If (status = = 133  retryCount  GATT_CONNECT_RETRY_MAX_COUNT) {if (BluetoothUtil. SwitchBlueState (false)) {/ / off bluetooth Handler. PostDelayed (() -  {the if (BluetoothUtil. SwitchBlueState (true)) {/ / 5 s, @override public void run() {connect(deviice, callback) {connect(deviice, callback); }}, 5000); } else {// Reopening Bluetooth failed connectDeviceError(); }}, 5000); } else {// Disable Bluetooth failed connectDeviceError(); } } } } private void connectDeviceError() { } }Copy the code

Bluetooth operation class, BluetoothUtil

public class BluetoothUtil { private static final String TAG = BluetoothUtil.class.getSimpleName(); Public static Boolean switchBlueState(Boolean isOpen) {BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); boolean suc; if (isOpen) { suc = adapter.enable(); Log.d(TAG, "open blue suc :" + suc); } else { suc = adapter.disable(); Log.d(TAG, "close blue suc :" + suc); } return suc; }}Copy the code

4、 FastBLe

Address: github.com/Jasonchenli…

FastBLe is an excellent BLE open source library with 4.4K Star on GitHub. It supports reconnection mechanism and connects devices stably.

5, summary

After repeated optimization, it was found that the occurrence of 133 error codes could not be completely eliminated, but could only be reduced. This problem also depends on the model. The Mi connection I tried is relatively stable, and OPPO often appears. In Ble development, it is easy to encounter. You still need Google at the protocol level and device vendors at the hardware level to optimize. What development can do is to improve the stability of Ble connections as much as possible. If you have a better idea, feel free to discuss it in the comments section

reference

Stackoverflow.com/questions/2…

medium.com/@martijn.va…

www.zhihu.com/question/24…

Github.com/Jasonchenli…

talarari

Getting error on descriptor write status 133 with bonded device

hey,
i’m getting some weird behavior with enabling notifications.
i’m developing an app that needs to connect to a ble peripheral automatically, i scan, find the device then bond with — device.createBond().
then i enable notifications from the device on the rx characteristic for the uart service.
this works fine for the first time, but when i use the bonded device to do the same the second time i get
a callback to descriptor write with status 133 sometimes followed by a connection state change callback with state 0 and status 22.

i could not find any info online for what status 133 or 22 mean.

any idea why this is happening? removing the bond makes it work again, but again, only for the first time, i cant complete the flow from a bonded device

philips77

Hi, regarding those errors, you may find some very, very short info here:
https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-5.1.1_r13/stack/include/gatt_api.h

Error 133, defined as: #define GATT_ERROR 0x85 is a general BLE error. It usually appears when a device is not reachable or… from any other occasion.
The error 22 is a connection error, which is defined there as #define GATT_CONN_TERMINATE_LOCAL_HOST HCI_ERR_CONN_CAUSE_LOCAL_HOST /* 0x16 connectionterminated by local host */. You’ll find other error codes «described» there as well.

Regarding the bonding problem, I’d say it depends very much which Android version or which device are you using. You may try to add some delays here and there to give the stack some more time. In the toolbox, in BLEManager, I wait 600ms after I get onConnectionStateChange(..) callback before calling gatt.discoverServices(). Also clearing the device cache usually helps, but it’s a hack and should not be used normally. To refresh the cache you have to call gatt.refresh() method using reflections. You’ll find it implemented in the DfuBaseService class in the DFU Library, here.

Did you try using nRF Toolbox or nRF Master Control Panel apps to connect to your service after you bond? Do you get similar results?

talarari

just tried the nrf toolbox app with the bonded device, got the exact same problem.
error on writing descriptor 133, error:0x16 gatt conn terminate local host

i added a 2 second delay after connecting gatt before doing anything and now it works.
thanks!

talarari

ok, was wrong, the delay did not fix it.
not sure what i can do

talarari

this usually doesnt happen when i initiate the disconnection from the device myself.
when the device disconnects becuase it was turned off and back on or when i walk away from it and come back then i always get this problems.
when i get the onConnectionStateChange event with disconnect state i still call gatt.disconnect and gatt.close but maybe something is not released properly.

any suggestions?

talarari

some more details, if i only save the ble device address and connect using bluetoothAdapter.getRemoteDevice(address) then i never have this problem.
it is only when bonding, maybe the bond information is no longer valid after my ble device restarts? what info does the bond keep?

philips77

Without bonding reconnecting is much more stable and reliable. Even if you get 133 you may repeat it and usually it works. But in come cases you must have bond (for example if you have secure informations, proximity etc.). Then you have a problem… :(
From my experience if any error occurs the bond information is lost on Android. The bond information contains the LTK — Long Term Key — a key used to encrypt the connection. This key is known by both sides and used to encrypt and decrypt packets. If one of sides does not have it, the other either refuses to connect (as it thinks it is not a valid device), tries to bond again or just connects without bonding, depending on the implementation.
You also may not rely on the getBondState() method from the device. If the device was bonded, but due to an error the LTK has been removed, the method still returns state bonded. The only reliable way I know to check if a device is still bonded after connection is using notifications/indications. A bonded devices should save values of CCCDs for each characteristic that have them and after reconnection you should start getting packets. You must remember to enable notifications or indications locally on the Android gatt.setCharacteristicNotification(characteristic, true); after you reconnect and do service discovery. If notifications were enabled (CCCD=0x0100) before, you should start receiving them. If you lost bond the CCCD value will be 0 (you may also read it just after you reconnect).

amibition521

I now face a situation on the following: the premise is that I will be connected with the equipment are stored locally, when off the device on automatic connection device, but now the callback connection for a long time, about 35S,I get the error 133, any good solution can shorten the feedback time and solution this 133 problem

philips77

In this case the 133 means that the device is not reachable. It doesn’t advertise or is out of range. Also, I think you can’t just connect to a device that you created in the code with the Mac address, you have to scan for it, or obtain from Bluetooth Adapter if it’s bonded.

This code may not work:

BluetoothDevice d = new BluetoothDevice("AA:33:66:44:66:77");
d.connectGatt(...);

philips77

Regarding my previous comment. The code snippet will work in 2 conditions:

  1. The device has Public address
  2. The device with given address has been scanned at least once before the connectGatt method is called.

Explanation:
The BLE address is in fact 49-bit long. The additional bit says whether the device is private or public. It is present in all advertising packets as well as in Connect Req packet.
http://j2abro.blogspot.no/2014/06/understanding-bluetooth-advertising.html
If the device has never been scanned, the Android does not know what type of address it is. The API allows only to specify the 48-bit long address. However, as private addresses are usually randomly generated, it’s highly unlikely that someone would know the address in real life scenario (debugging your device on you desk is not one of them). Therefore in that case they assume that the address is public and even if all 48-bits of your device are equal to those given in the parameter above, the connection attempt will fail.
However, if a device with such address was scanned at least once, its type was saved by the system. Then, when you create a BluetoothDevice object that way, or obtained it from a scanner, the Android knows what address type put in the Connect Request packet.

mjohn123

I know the issue may be closed but I have the same issue. I did not find any good solution. My issue only happen in some device such as Samsung Note 3. My error code is

onClientConnectionState() - status=22 clientIf=7

To solve that error, I used a delay before calling the readCharacteristic () function on the

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                try {
                    Thread.sleep(500);
                    readCustomCharacteristic();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

It can solve my issue. However, I do not think the Thread.sleep is a good solution because delay time (500ms) may be different among devices. In additions, the above error only happens on some device. It worked well with other devices. In BLE, do we have any callback function which can safely call the readCustomCharacteristic()?

This is my readCustomCharacteristic() function

public void readCustomCharacteristic() {
        /*check if the service is available on the device*/
        BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("00001c00-d102-11e1-9b23-00025b00123"));
        /*get the read characteristic from the service*/
        BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(UUID.fromString("00001233-d102-11e1-9b23-00025b00a5a5"));
		mBluetoothGatt.setCharacteristicNotification(mReadCharacteristic, true);
        BluetoothGattDescriptor descriptor = mReadCharacteristic.getDescriptor(
                UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        mBluetoothGatt.writeDescriptor(descriptor);
    }
 

thejeshgn

For me writing my own onDescriptorWriteRequest solved the issue. Specially adding mGattServer.sendResponse

 @Override
        public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, 
BluetoothGattDescriptor descriptor, 
                        boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
            Log.d("HELLO", "Our gatt server descriptor was written.");
            super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);
            Log.d("DONE", "Our gatt server descriptor was written.");

            //NOTE: Its important to send response. It expects response else it will disconnect
            if (responseNeeded) {
                mGattServer.sendResponse(device,
                        requestId,
                        BluetoothGatt.GATT_SUCCESS,
                        0,
                        value);

            }

        }

mjohn123

Hello thejeshgn, which issue did you solve? Status=133 or status=22 as my issue

thejeshgn

Issue of status=133 or status=2 while trying to write descriptor.

IgorGanapolsky

Any update on error 133? I am getting the same thing on Android 7.1.2.

cvergnaud

When you have too many connections opened, a 133 error can occur. Make sure you have closed all GattClient. I have a device that triggers quite often a 133 even if all connections are closed, my solution is to restart the connection process.
The trick of thejeshgn is «doing the job» but it is not solving the root cause. The remote device should respond to the WriteDescriptorRequest, and android should trigger the event «OnDescriptorWrite». Does this characteristic allow notification ?

Vhaiyue

In the process of upgrade,some mobile phone can be upgraded successfully, such as XIAOMI 4S,
But the connection is broken when the Implement progress is almost 10%, Such as HUAWEI 4X, the worse, sometimes it is only 3% when the connection is broken with BLE. What is wrong with it?

NivedithaKabbur

The error in my case was due to the encryption issue in the Bluetooth LE stack. Was getting the error btif_gatt_set_encryption_cb() — Encryption failed (1). Any idea about this error?

softlion

@thejeshgn onDescriptorWriteRequest is for an Android Gatt Server. Here the problem is for Android Gatt client. The client does not have any onDescriptorWriteRequest method to override.

AbhiShah29

Hi guys,

As @philips77 mentioned the error 133 is a common BLE error and its not just only android error.
When we perform multiple time connection and disconnection with the same device or with different devices the error occurs.
I have solved the issue by performing the below options.

If you are facing error 133 at the time of connection.

  • Add 500ms delay before connection request.
  • If an error still persists just disable ANDROID DEVICE BT and enable again. After enabling BT, wait for 500ms and then connect to BLE device.

If you are facing an error 133 at the time of Characteristic or Description read-write.

  • Add 500ms delay and try again
  • Disable notification and enable notification and retry read-write
  • Wait for 30sec before the read-write request. // The common BLE device has advertisement timeout interval of 30sec. In this 30sec they stop advertisement and restart again.

ashishTechmosoft

when i open first time ble then it connect perfectly but after disable and i am trying to cnnect again then it showing error 133 error.plz help

Я новичок в Android и теперь делаю простое приложение, которое требует записи некоторых данных в периферийное устройство.

На самом деле ничего не происходит в устройстве Samsung GT-S7272C. Но когда я переключаюсь на Sony LT29i, всегда будет статус 133, когда я пытаюсь записать определенную характеристику. Я дам короткий код.

BluetoothGattService syncService = gatt.getService(SYNC_DATA_SERVICE);
BluetoothGattCharacteristic tChar = syncService.getCharacteristic(SYNC_TIME_INPUT_CHAR);
if (tChar == null) throw new AssertionError("characteristic null when sync time!");

int diff = /*a int*/;
tChar.setValue(diff, BluetoothGattCharacteristic.FORMAT_SINT32, 0);
gatt.writeCharacteristic(tChar);

и функция onCharacteristicWrite:

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    Log.d(TAG, String.format("Sync: onCharWrite, status = %d", status));
    try {
        if (status != BluetoothGatt.GATT_SUCCESS) throw new AssertionError("Error on char write");
        super.onCharacteristicWrite(gatt, characteristic, status);
        if (characteristic.getUuid().equals(SYNC_TIME_INPUT_CHAR)) {
            BluetoothGattService syncService = gatt.getService(SYNC_DATA_SERVICE);
            BluetoothGattCharacteristic tChar = syncService.getCharacteristic(SYNC_HEIGHT_INPUT_CHAR);
            if (tChar == null) throw new AssertionError("characteristic null when sync time!");
            tChar.setValue(/*another int*/, BluetoothGattCharacteristic.FORMAT_SINT32, 0);
            gatt.writeCharacteristic(tChar);
        }
        else if {
            ...
        }
    } catch (AssertionError e) {
        ...
    }

Запись в первую характеристику не имеет ничего плохого, и управление достигнет onCharacteristicWrite и введите первый оператор if со статусом 0, что означает успех. Проблема — второе действие записи в операторе if, которое также вызывает функциюCharacteristicWrite, но дает статус 133, который не может быть найден на официальном сайте. Затем устройство автоматически отключается.

Я подтвердил правильность типа данных и смещения. И поскольку в другом устройстве он работает очень хорошо, я думаю, что могут быть некоторые незначительные различия в реализации стека bluetooth между различными устройствами, что я должен сделать что-то более сложное, чтобы решить эту проблему.

Я искал результат в течение длительного времени. Некоторые результаты приводят меня к исходному коду C (Извините, я отправлю ссылку ниже, потому что у меня недостаточно репутации, чтобы опубликовать более 2 ссылок), но я могу только найти, что 133 означает GATT_ERROR там, что не более полезно, чем просто 133. Я также нашел проблему в группе google, обсуждая некоторые знакомые вопросы, но мне не удалось найти решение здесь.

Мне немного грустно, потому что, если это что-то не так с кодом C, даже если я могу найти то, что неправильно, у меня все еще нет возможности сделать это правильно в моем собственном коде, не так ли?

Я надеюсь, что у кого-то есть знакомый опыт и может дать мне несколько предложений. Большое спасибо!

ссылки:

  • Исходный код C: https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-4.4.2_r1/stack/include/gatt_api.h

  • Проблема: https://code.google.com/p/android/issues/detail?id=58381

cmkessell

Starting Member

  • Total Posts : 77
  • Reward points : 0
  • Joined: 2007/09/03 02:55:13
  • Location: 0
  • Status: offline

Has anyone successfully connected to a RN4677 module in BLE mode?

 It works fine in classic Bluetooth mode but when I try to connect using BLE from my Android phone (using the nRF Master Control app) the connection disconnects almost immediately with a GATT Error 133.  It’s unclear if the problem lies with my phone, Android, or the RN4677 (which is definitely set to Dual mode.)

 In case it helps this is the log from the nRF Master Control app:

D 11:15:20.473 gatt.close()
V 11:15:20.498 Connecting to 8C:DE:52:B1:BF:B3…
D 11:15:20.508 gatt = device.connectGatt(autoConnect = false)
D 11:15:21.851 [Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED
D 11:15:21.981 [Callback] Connection state changed with status: 133 and new state: DISCONNECTED (0)
E 11:15:21.991 Error 133 (0x85): GATT ERROR
D 11:15:25.586 [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED

cmkessell

Starting Member

  • Total Posts : 77
  • Reward points : 0
  • Joined: 2007/09/03 02:55:13
  • Location: 0
  • Status: offline

Re: Has anyone used RN4677 in BLE mode?


2015/09/16 10:22:48

(permalink)

To answer my own question (in case it helps others), I managed to communicate with the RN4677 using BLE from an iPad running the ISSC BLETR app.  So I guess my problems lie with Android or the apps I was using.

 There does appear to be an Android equivalent of the ISSC BLETR app called Bluebit on the GitHub site (for some reason I can’t post the link). However that site just has the source code; I can’t locate a copy of the compiled app.  Unfortunately I’m not an Android developer; the code is old and doesn’t seem to load into the latest Android Studio.  Can anyone compile it?

post edited by cmkessell — 2015/09/16 10:27:58

Jim Nickerson

User 452

  • Total Posts : 7188
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline

Re: Has anyone used RN4677 in BLE mode?


2015/09/16 11:39:16

(permalink)

cmkessell
 (for some reason I can’t post the link). 

Posting images, links and code  http://www.microchip.com/forums/FindPost/777101
Edit: your scores are 0, they were reset when this policy began

post edited by Jim Nickerson — 2015/09/16 11:42:12

cmkessell

Starting Member

  • Total Posts : 77
  • Reward points : 0
  • Joined: 2007/09/03 02:55:13
  • Location: 0
  • Status: offline

Re: Has anyone used RN4677 in BLE mode?


2015/09/16 12:41:57

(permalink)

Ah, thanks.  The link I was referring to is

https://github.com/ISSC/Bluebit

Jim Nickerson

User 452

  • Total Posts : 7188
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline

Re: Has anyone used RN4677 in BLE mode?


2015/09/16 12:44:04

(permalink)

No problem, and now you have some scores ( I starred your post ).

Flying Al

New Member

  • Total Posts : 12
  • Reward points : 0
  • Joined: 2015/03/08 23:52:31
  • Location: 0
  • Status: offline

Re: Has anyone used RN4677 in BLE mode?


2015/10/10 02:45:54

(permalink)

Does anyone have RN4677 BLE working with Android yet? I have tried Bluebit and nRF Master Control on both Nexus 4 and OnePlus One and have not been able to get a working connection. I can get RN4677 SPP working on both easily. 

cmkessell

Starting Member

  • Total Posts : 77
  • Reward points : 0
  • Joined: 2007/09/03 02:55:13
  • Location: 0
  • Status: offline

Re: Has anyone used RN4677 in BLE mode?


2015/10/10 09:23:31

(permalink)

Unfortunately I never got it working in BLE with Android. 

RISC

Super Member

  • Total Posts : 6195
  • Reward points : 0
  • Status: offline

Re: Has anyone used RN4677 in BLE mode?


2015/10/10 13:06:28

(permalink)

Hi,
BLE works with Android BUT you must use at lease KitKat version (V4.4).
I have used RN4020 (single mode) and BM77 (dual mode) with Android (a couple of different smartphones) but generally speaking it seems connections are easier with iOS devices.
I have always used the apk applications provided by Microchip for each device but some «generic» apps should also work (I mean not applications available from other manufacturers which may only work with their own devices).

 For RN4677, I suggest you follow the examples from the RN4677-PICTAIL user manual
Regards

post edited by RISC — 2015/10/10 13:07:47

Понравилась статья? Поделить с друзьями:
  • Error 1328 error applying patch to file
  • Error 1327 invalid drive error
  • Error 1326 dameware
  • Error 1325 is not a valid short file name veeam
  • Error 1324 путь к папке c содержит недопустимый символ