Commit 18fd8bf0 authored by puthik's avatar puthik Committed by Commit bot
Browse files

arc: bluetooth: Implement Gatt notify



This patch does the following
- Implement the notification to arc bridge when remote
  Gatt characteristic value changed.
- Make Android request for writing to CCC Descriptor does
  nothing because Chrome bundle that to register/deregister
  for notification.

BUG=b:28250518
TEST=Test battery notification with Pixel C Keyboard
Signed-off-by: default avatarPuthikorn Voravootivat <puthik@google.com>
Review-Url: https://codereview.chromium.org/2085083002
Cr-Commit-Position: refs/heads/master@{#402331}
parent cb7c961a
......@@ -45,13 +45,14 @@ using device::BluetoothRemoteGattService;
using device::BluetoothUUID;
namespace {
const int kMinBtleVersion = 1;
const uint32_t kGattReadPermission =
constexpr int32_t kMinBtleVersion = 1;
constexpr int32_t kMinBtleNotifyVersion = 2;
constexpr uint32_t kGattReadPermission =
BluetoothGattCharacteristic::Permission::PERMISSION_READ |
BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
BluetoothGattCharacteristic::Permission::
PERMISSION_READ_ENCRYPTED_AUTHENTICATED;
const uint32_t kGattWritePermission =
constexpr uint32_t kGattWritePermission =
BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
BluetoothGattCharacteristic::Permission::
......@@ -134,10 +135,8 @@ void ArcBluetoothBridge::DeviceAdded(BluetoothAdapter* adapter,
arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
std::move(properties));
if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
if (!CheckBluetoothInstanceVersion(kMinBtleVersion))
return;
}
mojom::BluetoothAddressPtr addr =
mojom::BluetoothAddress::From(device->GetAddress());
......@@ -208,10 +207,8 @@ void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter,
if (!HasBluetoothInstance())
return;
if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
if (!CheckBluetoothInstanceVersion(kMinBtleVersion))
return;
}
mojom::BluetoothAddressPtr addr =
mojom::BluetoothAddress::From(device->GetAddress());
......@@ -260,7 +257,30 @@ void ArcBluetoothBridge::GattCharacteristicValueChanged(
BluetoothAdapter* adapter,
BluetoothRemoteGattCharacteristic* characteristic,
const std::vector<uint8_t>& value) {
// Placeholder for GATT client functionality
if (!HasBluetoothInstance())
return;
if (!CheckBluetoothInstanceVersion(kMinBtleNotifyVersion))
return;
BluetoothRemoteGattService* service = characteristic->GetService();
BluetoothDevice* device = service->GetDevice();
mojom::BluetoothAddressPtr address =
mojom::BluetoothAddress::From(device->GetAddress());
mojom::BluetoothGattServiceIDPtr service_id =
mojom::BluetoothGattServiceID::New();
service_id->is_primary = service->IsPrimary();
service_id->id = mojom::BluetoothGattID::New();
service_id->id->inst_id = ConvertGattIdentifierToId(service->GetIdentifier());
service_id->id->uuid = mojom::BluetoothUUID::From(service->GetUUID());
mojom::BluetoothGattIDPtr char_id = mojom::BluetoothGattID::New();
char_id->inst_id = ConvertGattIdentifierToId(characteristic->GetIdentifier());
char_id->uuid = mojom::BluetoothUUID::From(characteristic->GetUUID());
arc_bridge_service()->bluetooth_instance()->OnGattNotify(
std::move(address), std::move(service_id), std::move(char_id),
true /* is_notify */, mojo::Array<uint8_t>::From(value));
}
void ArcBluetoothBridge::GattDescriptorValueChanged(
......@@ -540,10 +560,8 @@ void ArcBluetoothBridge::OnGattConnectStateChanged(
if (!HasBluetoothInstance())
return;
if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
if (!CheckBluetoothInstanceVersion(kMinBtleVersion))
return;
}
DCHECK(addr);
......@@ -905,6 +923,19 @@ void ArcBluetoothBridge::WriteGattDescriptor(
DCHECK(descriptor);
DCHECK(descriptor->GetPermissions() & kGattWritePermission);
// To register / deregister GATT notification, we need to
// 1) Write to CCC Descriptor to enable/disable the notification
// 2) Ask BT hw to register / deregister the notification
// The Chrome API groups both steps into one API, and does not support writing
// directly to the CCC Descriptor. Therefore, until we fix
// https://crbug.com/622832, we return successfully when we encounter this.
// TODO(http://crbug.com/622832)
if (descriptor->GetUUID() ==
BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()) {
OnGattWriteDone(callback);
return;
}
descriptor->WriteRemoteDescriptor(
value->value.To<std::vector<uint8_t>>(),
base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
......@@ -1320,4 +1351,14 @@ void ArcBluetoothBridge::SendCachedPairedDevices() const {
}
}
bool ArcBluetoothBridge::CheckBluetoothInstanceVersion(
int32_t version_need) const {
int32_t version = arc_bridge_service()->bluetooth_version();
if (version >= version_need)
return true;
LOG(WARNING) << "Bluetooth instance is too old (version " << version
<< ") need version " << version_need;
return false;
}
} // namespace arc
......@@ -264,6 +264,7 @@ class ArcBluetoothBridge
void SendCachedDevicesFound() const;
bool HasBluetoothInstance() const;
bool CheckBluetoothInstanceVersion(int32_t version_need) const;
template <class T>
T* FindGattObjectFromUuid(const std::vector<T*> objs,
......
......@@ -321,4 +321,9 @@ interface BluetoothInstance {
uint16 end_handle);
[MinVersion=1] OnServicesAdded@12(BluetoothAddress remote_addr,
array<BluetoothGattDBElement> db);
[MinVersion=2] OnGattNotify@13(BluetoothAddress remote_addr,
BluetoothGattServiceID service_id,
BluetoothGattID char_id,
bool is_notify,
array<uint8> value);
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment