Android Central с GattServer

Я пытаюсь запрограммировать Bluetooth с низким энергопотреблением - AlertNotificationService (ANS). Это немного странный сервис, потому что обычно сервисы работают на периферийном устройстве GAP. Но ANS работает на центральном GAP. Таким образом, типичный способ работы должен быть, например, таким:

Watch - GAP peripheral (broadcasting), GATT client
Phone - GAP central                  , GATT server

В принципе у меня работает, но не всегда. И эта нестабильность мне очень чужда. Когда я смотрю с помощью анализатора bluetooth LE, я вижу, что сервер Android GATT иногда сообщает, что в моем профиле нет характеристик...

Это выглядит так: «смотреть» запросить мой сервис GATT (я знаю, что это проприетарный, а не ANS UUID)

Slave->Master ATT Rcvd Find By Type Value Request, GATT Primary Service Declaration 11:22:33:44:11:22:33:44:11:76:62:65:01:00:00:00

Телефон говорит, что служба существует, начиная с дескриптора 0x35.

Master->Slave ATT Rcvd Find By Type Value Response Handle: 0x0035

Часы запрашивают характеристики с дескриптора 0x35

Slave->Master ATT Rcvd Read By Type Request, GATT Characteristic Declaration, Handles: 0x0035..0xffff

Но телефон иногда неправильно говорит, что с этой ручки нет характеристики:

Master->Slave ATT Rcvd Error Response - Attribute Not Found, Handle: 0x0035

Когда я добавляю услугу и характеристику на сервер GATT, я всегда получаю «истину» от функций. Я делаю это так:

BluetoothGattService service =new BluetoothGattService(Vbe_AnsExt.UUID_SERVICE,
        BluetoothGattService.SERVICE_TYPE_PRIMARY);

BluetoothGattCharacteristic characApp =
        new BluetoothGattCharacteristic(Vbe_AnsExt.UUID_CharacApp,
                BluetoothGattCharacteristic.PROPERTY_READ ,
                BluetoothGattCharacteristic.PERMISSION_READ);

BluetoothGattCharacteristic characMsg =
        new BluetoothGattCharacteristic(Vbe_AnsExt.UUID_CharacMsg,
                BluetoothGattCharacteristic.PROPERTY_READ ,
                BluetoothGattCharacteristic.PERMISSION_READ );

boolean ret;
ret = service.addCharacteristic(characApp);
Log.i("vbeInit_ASN_Ext_Server","addCharApp  retruned: "+ret);
ret = service.addCharacteristic(characMsg);
Log.i("vbeInit_ASN_Ext_Server","addCharMsg  retruned: "+ret);

ret = mGattServer.addService(service);
Log.i("vbeInit_ASN_Ext_Server","addService  retruned: "+ret);

Есть идеи, в чем может быть проблема? Я заметил, что есть функция BluetoothGattServer::connect(). Я не уверен, как его использовать. Я использую стандартный BluetoothDevice::connectGatt(). Но я думаю, что если я сделаю что-то не так, это не сработает никогда - не иногда... Я использую Android M (6.0.1) на Samsung SM-G920F.

[ОБНОВИТЬ]

Я заметил, что после перезагрузки телефона он всегда работает. После закрытия и повторного открытия приложения оно обычно не работает. Не работает по-разному ->

  • иногда характеристика не обнаруживается;
  • иногда обнаруживается только первая характеристика
  • иногда обнаруживается только последняя (вторая) характеристика.

Когда я запускаю Gatt Server, я делаю это так:

mGattServer = bluetoothManager.openGattServer(appContext, mGattServerCallback);
mGattServer.clearServices();

Когда я закрываю приложение (onDestroy()), я закрываю gattserver:

mGattServer.close();

Я также пробовал не закрывать сервер ГАТТ, но это не помогло. Есть идеи, что может пойти не так между закрытием и повторным открытием?


person Vit Bernatik    schedule 19.09.2016    source источник


Ответы (1)


Так что, возможно, я нашел причину. Я добавляю 2 сервиса: ANS и мой сервис ANS_extension. Вроде помогает когда жду после добавления услуги по обратному звонку onServiceAdded()

Итак, теперь это выглядит так:

public static UUID UUID_SupportedNewAlertCategory     = UUID.fromString("00002a47-0000-1000-8000-00805f9b34fb");
public static UUID UUID_NewAlert                      = UUID.fromString("00002a46-0000-1000-8000-00805f9b34fb");
// descriptor used for enabling notify feature
public static UUID UUID_Descr_new                     = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
mGattServer = bluetoothManager.openGattServer(appContext, mGattServerCallback);
mGattServer.clearServices();
waitServiceAdded = true;
BluetoothGattService service = new BluetoothGattService(Vbe_Ans.UUID_SERVICE,
                BluetoothGattService.SERVICE_TYPE_PRIMARY);

BluetoothGattCharacteristic characSupportedNewAlerCategory =
                new BluetoothGattCharacteristic(Vbe_Ans.UUID_SupportedNewAlertCategory,
                        BluetoothGattCharacteristic.PROPERTY_READ ,
                        BluetoothGattCharacteristic.PERMISSION_READ);
BluetoothGattCharacteristic characNewAlert =
                new BluetoothGattCharacteristic(Vbe_Ans.UUID_NewAlert,
                        BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                        BluetoothGattCharacteristic.PERMISSION_READ );
BluetoothGattDescriptor bgd = new BluetoothGattDescriptor(UUID_Descr_new,
                BluetoothGattDescriptor.PERMISSION_READ | BluetoothGattDescriptor.PERMISSION_WRITE);

characNewAlert.addDescriptor(bgd);
...
ret = service.addCharacteristic(characSupportedNewAlerCategory);
ret = service.addCharacteristic(characNewAlert);
...
ret = mGattServer.addService(service);
while(waitServiceAdded);

waitServiceAdded = true;
//init second service similar way as previous
while(waitServiceAdded);

Затем я очищаю флаг ожидания waitServiceAdded в обратном вызове сервера GATT. (Я новичок в Java, поэтому вы можете использовать некоторую синхронизацию мьютекса потока для доступа к логическому значению?)

private BluetoothGattServerCallback mGattServerCallback = new BluetoothGattServerCallback() {
@Override
  public void onServiceAdded (int status,
                                    BluetoothGattService service){
    waitServiceAdded = false;
  }
person Vit Bernatik    schedule 20.09.2016