Android Bluetooth-статус 133 в onCharacteristicwrite

Я новичок в 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

5 ответов

Решение

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

Проблема оказалась в том, что 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_PARAMETER0x0087 (135)
  • GATT_NO_RESOURCES0x0080 (128)
  • GATT_INTERNAL_ERROR0x0081 (129)
  • GATT_WRONG_STATE0x0082 (130)
  • GATT_DB_FULL0x0083 (131)
  • GATT_BUSY0x0084 (132)
  • GATT_ERROR0x0085 (133)
  • GATT_CMD_STARTED0x0086 (134)
  • GATT_PENDING0x0088 (136)
  • GATT_AUTH_FAIL0x0089 (137)
  • GATT_MORE0x008a (138)
  • GATT_INVALID_CFG0x008b (139)
  • GATT_SERVICE_STARTED0x008c (140)
  • GATT_ENCRYPED_MITMGATT_SUCCESS
  • GATT_ENCRYPED_NO_MITM0x008d (141)
  • GATT_NOT_ENCRYPTED0x008e (142)

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

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

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

У меня была та же проблема с ошибкой 133, и мне пришлось использовать надежную запись , чтобы заставить ее работать (извините за код Kotlin вместо Java):

      fun BluetoothGatt.myWrite(characteristic: BluetoothGattCharacteristic, payload: ByteArray) {
  
  // Set write type
  characteristic.writeType =  when {
    characteristic.containsProperty(BluetoothGattCharacteristic.PROPERTY_WRITE) -> BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
    characteristic.containsProperty(BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) -> BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
    else -> error("Characteristic ${characteristic.uuid} cannot be written to")
  }
  
  // set the payload
  characteristic.setValue(payload)

  // write
  this.beginReliableWrite()
  this.writeCharacteristic(characteristic)
  this.executeReliableWrite()

}

с использованием функции расширения:

      fun BluetoothGattCharacteristic.containsProperty(property: Int): Boolean {
  return properties and property != 0
}
Другие вопросы по тегам