Android Bluetooth Low Energy Получение ответа на конкретный запрос

Есть кое-что, чего я не совсем понимаю в использовании Gatt для связи с устройством BLE. Согласно этому: https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#connectGatt(android.content.Context,%20boolean,%20android.bluetooth.BluetoothGattCallback)

BluetoothGatt gatt = device.connectGatt(context,true,new BluetoothGattCallback(){....})

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

Я не понимаю, как какая запись соответствует какому обратному вызову чтения?

Сигнатуры этого метода:

public void onCharacteristicRead (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
public void onCharacteristicWrite (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)

so if I do:

BluetoothGattCharacteristic char = gatt.getService(UART_SERVICE_UUID).getCharacteristic(UART_TX_CHARACTERISTIC_UUID);
char1.setValue("command1");
gatt.writeCharacteristic(char);
char1.setValue("command2");
gatt.writeCharacteristic(char);

в обратном вызове onCharacteristicRead, как мне узнать, предназначена ли характеристика .getStringValue () для command1 или command2?

Спасибо!


person talarari    schedule 24.06.2015    source источник
comment
Я знаю, что это старый, но как насчет выбора одного ответа в качестве принятого?   -  person Rob Gorman    schedule 01.08.2018


Ответы (4)


При использовании BluetoothGatt.writeCharacteristic() и связанных BluetoothGatt методов необходимо знать несколько важных моментов.

  1. Обратите внимание, что writeCharacteristic() (и многие другие методы BluetoothGatt) возвращают логическое значение. Если результат ложный, это означает, что операция не была успешно запущена. Когда это происходит? См. Следующий пункт.

  2. Используя объект aBluetoothGatt, невозможно запустить две операции одновременно. Вызов для запуска второго завершится ошибкой и вернет false. После вызова writeCharacteristic() код должен дождаться ответа обратного вызова (onCharacteristicWrite), прежде чем выполнить еще одну запись. В примере кода для этого вопроса второй вызов writeCharacteristic() почти наверняка вернет false по этой причине.

Таким образом, если каждая операция BluetoothGatt ожидает обратного вызова для ранее выданной команды, вы можете успешно соединить инициирование команд и обратные вызовы - на самом деле вы вынуждены.

person Rob Gorman    schedule 24.06.2015

В этой реализации вы должны дождаться onCharacteristicWrite после первой записи перед выполнением следующей операции записи. Но это справедливо, если вы не изменили тип записи с setWriteType (int writeType) со значения по умолчанию WRITE_TYPE_DEFAULT, который обращается к операциям записи. Возможно, вам потребуется сохранить состояние для этих операций.

Другой вариант - иметь в ответе код команды (например, 1 байт), чтобы вы могли сопоставить его с командой.

person istirbu    schedule 24.06.2015

private String heartRate;

private String temperature;

...

char.setValue("command1");

gatt.writeCharacteristic(char);

...

Затем в onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) проверьте, равна ли переменная heartRate нулю. Если это так, получите значение характеристики и присвойте его переменной heartRate. Затем сделайте characteristic.setValue("command2");

gatt.writeCharacteristic(characteristic);, и он снова вызовет onCharacteristicWrite(...).

Если переменная heartRate не равна нулю, получите значение и присвойте его переменной температуры. Вы также можете использовать UUID переданной характеристики, чтобы различать, для чего это значение.

Бонус: одна характеристика может содержать несколько дескрипторов. У вас может быть два дескриптора с собственным UUID для этой характеристики. Затем вы можете позвонить characteristic.getDescriptor(UUIDDescriptor).getValue().

person nickle_nine    schedule 25.06.2015

Как я уже объяснял, здесь, я дам ответ, который хотел бы получить, когда начну играть с GATT BLE.

Чтобы создать своего рода API (запрос с параметром (ами) = ›ответ, как указано в заголовке этого вопроса), выполните следующие действия:

  • create a GATT service with:
    • a Write characteristic (unlike read characteristic, write one receives data) to manage request (with parameter(s) through the data payload)
    • Характеристика чтения для управления ответом как уведомление
    • дескриптор конфигурации характеристик клиента для характеристики чтения для включения уведомления (стандартный 16-битный UUID CCCD: 0x2902).
  • Клиент пишет дескриптор конфигурации характеристик клиента, чтобы включить уведомление / индикацию (один раз после соединения)
  • Запрос на запись клиента Характеристика (запрос)
  • Статус ответа сервера GATT ОК для записи Характеристика (запрос)
  • Индикация отправки сервера GATT (не ожидает подтверждения от клиента) с данными из считанной характеристики

Конкретно, как это сделать с FreeRTOS?

Создайте свою службу GATT следующим образом:

static const BTAttribute_t pxAttributeTable[] =
{
    {
        .xServiceUUID =
        {
            .uu.uu128 = GATT_SERVICE_UUID,
            .ucType = eBTuuidType128

        }
    },
    {
        .xAttributeType = eBTDbCharacteristic,
         .xCharacteristic =
        {
            .xUuid =
            {
                .uu.uu128 = GATT_CHARACTERISTIC_REQUEST_UUID,
                .ucType = eBTuuidType128
            },
            .xPermissions = (IOT_BLE_CHAR_WRITE_PERM),
            .xProperties = (eBTPropWrite)
        }
    },
    {
        .xAttributeType = eBTDbCharacteristic,
        .xCharacteristic =
        {
            .xUuid = 
            {
                .uu.uu128 = GATT_CHARACTERISTIC_RESPONSE_UUID,
                .ucType = eBTuuidType128
            },
            .xPermissions = (IOT_BLE_CHAR_READ_PERM),
            .xProperties = (eBTPropRead | eBTPropNotify)
        }
    },
    {
        .xAttributeType = eBTDbDescriptor,
        .xCharacteristicDescr =
        {
            .xUuid = 
            {
                .uu.uu16 = 0x2902,
                .ucType = eBTuuidType16
            },
            .xPermissions = (IOT_BLE_CHAR_READ_PERM | IOT_BLE_CHAR_WRITE_PERM)
        }
     }
};
person Romain DEQUIDT    schedule 06.01.2021