Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h" | 5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h" |
| 6 | 6 |
| 7 #include <bluetooth/bluetooth.h> | 7 #include <bluetooth/bluetooth.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 using device::BluetoothLocalGattService; | 47 using device::BluetoothLocalGattService; |
| 48 using device::BluetoothRemoteGattCharacteristic; | 48 using device::BluetoothRemoteGattCharacteristic; |
| 49 using device::BluetoothRemoteGattDescriptor; | 49 using device::BluetoothRemoteGattDescriptor; |
| 50 using device::BluetoothRemoteGattService; | 50 using device::BluetoothRemoteGattService; |
| 51 using device::BluetoothTransport; | 51 using device::BluetoothTransport; |
| 52 using device::BluetoothUUID; | 52 using device::BluetoothUUID; |
| 53 | 53 |
| 54 namespace { | 54 namespace { |
| 55 constexpr int32_t kMinBtleVersion = 1; | 55 constexpr int32_t kMinBtleVersion = 1; |
| 56 constexpr int32_t kMinBtleNotifyVersion = 2; | 56 constexpr int32_t kMinBtleNotifyVersion = 2; |
| 57 constexpr int32_t kMinGattServerVersion = 3; | |
| 57 constexpr uint32_t kGattReadPermission = | 58 constexpr uint32_t kGattReadPermission = |
| 58 BluetoothGattCharacteristic::Permission::PERMISSION_READ | | 59 BluetoothGattCharacteristic::Permission::PERMISSION_READ | |
| 59 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | | 60 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | |
| 60 BluetoothGattCharacteristic::Permission:: | 61 BluetoothGattCharacteristic::Permission:: |
| 61 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; | 62 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; |
| 62 constexpr uint32_t kGattWritePermission = | 63 constexpr uint32_t kGattWritePermission = |
| 63 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | | 64 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | |
| 64 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | | 65 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | |
| 65 BluetoothGattCharacteristic::Permission:: | 66 BluetoothGattCharacteristic::Permission:: |
| 66 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; | 67 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; |
| 67 constexpr int32_t kInvalidGattAttributeHandle = -1; | 68 constexpr int32_t kInvalidGattAttributeHandle = -1; |
| 68 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 | 69 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 |
| 69 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. | 70 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. |
| 70 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; | 71 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; |
| 72 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 | |
| 73 // The maximum length of an attribute value shall be 512 octets. | |
| 74 constexpr int kMaxGattAttributeLength = 512; | |
| 71 | 75 |
| 72 using GattStatusCallback = | 76 using GattStatusCallback = |
| 73 base::Callback<void(arc::mojom::BluetoothGattStatus)>; | 77 base::Callback<void(arc::mojom::BluetoothGattStatus)>; |
| 74 using GattReadCallback = | 78 using GattReadCallback = |
| 75 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; | 79 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; |
| 76 | 80 |
| 77 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a | 81 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a |
| 78 // Convert the last 4 characters of |identifier| to an | 82 // Convert the last 4 characters of |identifier| to an |
| 79 // int, by interpreting them as hexadecimal digits. | 83 // int, by interpreting them as hexadecimal digits. |
| 80 int ConvertGattIdentifierToId(const std::string identifier) { | 84 int ConvertGattIdentifierToId(const std::string identifier) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 135 void OnGattReadError(const GattReadCallback& callback, | 139 void OnGattReadError(const GattReadCallback& callback, |
| 136 BluetoothGattService::GattErrorCode error_code) { | 140 BluetoothGattService::GattErrorCode error_code) { |
| 137 arc::mojom::BluetoothGattValuePtr gattValue = | 141 arc::mojom::BluetoothGattValuePtr gattValue = |
| 138 arc::mojom::BluetoothGattValue::New(); | 142 arc::mojom::BluetoothGattValue::New(); |
| 139 gattValue->status = | 143 gattValue->status = |
| 140 mojo::ConvertTo<arc::mojom::BluetoothGattStatus>(error_code); | 144 mojo::ConvertTo<arc::mojom::BluetoothGattStatus>(error_code); |
| 141 gattValue->value = nullptr; | 145 gattValue->value = nullptr; |
| 142 callback.Run(std::move(gattValue)); | 146 callback.Run(std::move(gattValue)); |
| 143 } | 147 } |
| 144 | 148 |
| 149 // Callback function for mojom::BluetoothInstance::RequestGattRead | |
| 150 void OnGattServerRead( | |
| 151 const BluetoothLocalGattService::Delegate::ValueCallback& success_callback, | |
| 152 const BluetoothLocalGattService::Delegate::ErrorCallback& error_callback, | |
| 153 arc::mojom::BluetoothGattStatus status, | |
| 154 mojo::Array<uint8_t> value) { | |
| 155 if (status == arc::mojom::BluetoothGattStatus::GATT_SUCCESS) | |
| 156 success_callback.Run(value.To<std::vector<uint8_t>>()); | |
| 157 else | |
| 158 error_callback.Run(); | |
| 159 } | |
| 160 | |
| 161 // Callback function for mojom::BluetoothInstance::RequestGattWrite | |
| 162 void OnGattServerWrite( | |
| 163 const base::Closure& success_callback, | |
| 164 const BluetoothLocalGattService::Delegate::ErrorCallback& error_callback, | |
| 165 arc::mojom::BluetoothGattStatus status) { | |
| 166 if (status == arc::mojom::BluetoothGattStatus::GATT_SUCCESS) | |
| 167 success_callback.Run(); | |
| 168 else | |
| 169 error_callback.Run(); | |
| 170 } | |
| 171 | |
| 172 bool IsGattOffsetValid(int offset) { | |
| 173 return 0 <= offset && offset < kMaxGattAttributeLength; | |
| 174 } | |
| 175 | |
| 145 } // namespace | 176 } // namespace |
| 146 | 177 |
| 147 namespace arc { | 178 namespace arc { |
| 148 | 179 |
| 149 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) | 180 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) |
| 150 : ArcService(bridge_service), binding_(this), weak_factory_(this) { | 181 : ArcService(bridge_service), binding_(this), weak_factory_(this) { |
| 151 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { | 182 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { |
| 152 VLOG(1) << "registering bluetooth adapter"; | 183 VLOG(1) << "registering bluetooth adapter"; |
| 153 BluetoothAdapterFactory::GetAdapter(base::Bind( | 184 BluetoothAdapterFactory::GetAdapter(base::Bind( |
| 154 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); | 185 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 true /* is_notify */, mojo::Array<uint8_t>::From(value)); | 403 true /* is_notify */, mojo::Array<uint8_t>::From(value)); |
| 373 } | 404 } |
| 374 | 405 |
| 375 void ArcBluetoothBridge::GattDescriptorValueChanged( | 406 void ArcBluetoothBridge::GattDescriptorValueChanged( |
| 376 BluetoothAdapter* adapter, | 407 BluetoothAdapter* adapter, |
| 377 BluetoothRemoteGattDescriptor* descriptor, | 408 BluetoothRemoteGattDescriptor* descriptor, |
| 378 const std::vector<uint8_t>& value) { | 409 const std::vector<uint8_t>& value) { |
| 379 // Placeholder for GATT client functionality | 410 // Placeholder for GATT client functionality |
| 380 } | 411 } |
| 381 | 412 |
| 413 template <class LocalGattAttribute> | |
| 414 void ArcBluetoothBridge::OnGattAttributeReadRequest( | |
| 415 const BluetoothDevice* device, | |
| 416 const LocalGattAttribute* gatt_obj, | |
|
palmer
2016/07/22 23:17:01
Nit: Might be better to name this |attribute|. (An
puthik_chromium
2016/07/23 00:20:28
Done.
| |
| 417 int offset, | |
| 418 const ValueCallback& success_callback, | |
| 419 const ErrorCallback& error_callback) { | |
| 420 DCHECK(CalledOnValidThread()); | |
| 421 if (!HasBluetoothInstance() || | |
| 422 !CheckBluetoothInstanceVersion(kMinGattServerVersion) || | |
| 423 !IsGattOffsetValid(offset)) { | |
| 424 error_callback.Run(); | |
| 425 return; | |
| 426 } | |
| 427 | |
| 428 DCHECK(gatt_handle_.find(gatt_obj->GetIdentifier()) != gatt_handle_.end()); | |
| 429 | |
| 430 arc_bridge_service()->bluetooth()->instance()->RequestGattRead( | |
| 431 mojom::BluetoothAddress::From(device->GetAddress()), | |
| 432 gatt_handle_[gatt_obj->GetIdentifier()], offset, false /* is_long */, | |
| 433 base::Bind(&OnGattServerRead, success_callback, error_callback)); | |
| 434 } | |
| 435 | |
| 436 template <class LocalGattAttribute> | |
| 437 void ArcBluetoothBridge::OnGattAttributeWriteRequest( | |
| 438 const BluetoothDevice* device, | |
| 439 const LocalGattAttribute* gatt_obj, | |
| 440 const std::vector<uint8_t>& value, | |
| 441 int offset, | |
| 442 const base::Closure& success_callback, | |
| 443 const ErrorCallback& error_callback) { | |
| 444 DCHECK(CalledOnValidThread()); | |
| 445 if (!HasBluetoothInstance() || | |
| 446 !CheckBluetoothInstanceVersion(kMinGattServerVersion) || | |
| 447 !IsGattOffsetValid(offset)) { | |
| 448 error_callback.Run(); | |
| 449 return; | |
| 450 } | |
| 451 | |
| 452 DCHECK(gatt_handle_.find(gatt_obj->GetIdentifier()) != gatt_handle_.end()); | |
| 453 | |
| 454 arc_bridge_service()->bluetooth()->instance()->RequestGattWrite( | |
| 455 mojom::BluetoothAddress::From(device->GetAddress()), | |
| 456 gatt_handle_[gatt_obj->GetIdentifier()], offset, | |
| 457 mojo::Array<uint8_t>::From(value), | |
| 458 base::Bind(&OnGattServerWrite, success_callback, error_callback)); | |
| 459 } | |
| 460 | |
| 382 void ArcBluetoothBridge::OnCharacteristicReadRequest( | 461 void ArcBluetoothBridge::OnCharacteristicReadRequest( |
| 383 const BluetoothDevice* device, | 462 const BluetoothDevice* device, |
| 384 const BluetoothLocalGattCharacteristic* characteristic, | 463 const BluetoothLocalGattCharacteristic* characteristic, |
| 385 int offset, | 464 int offset, |
| 386 const ValueCallback& callback, | 465 const ValueCallback& callback, |
| 387 const ErrorCallback& error_callback) {} | 466 const ErrorCallback& error_callback) { |
| 467 OnGattAttributeReadRequest(device, characteristic, offset, callback, | |
| 468 error_callback); | |
| 469 } | |
| 388 | 470 |
| 389 void ArcBluetoothBridge::OnCharacteristicWriteRequest( | 471 void ArcBluetoothBridge::OnCharacteristicWriteRequest( |
| 390 const BluetoothDevice* device, | 472 const BluetoothDevice* device, |
| 391 const BluetoothLocalGattCharacteristic* characteristic, | 473 const BluetoothLocalGattCharacteristic* characteristic, |
| 392 const std::vector<uint8_t>& value, | 474 const std::vector<uint8_t>& value, |
| 393 int offset, | 475 int offset, |
| 394 const base::Closure& callback, | 476 const base::Closure& callback, |
| 395 const ErrorCallback& error_callback) {} | 477 const ErrorCallback& error_callback) { |
| 478 OnGattAttributeWriteRequest(device, characteristic, value, offset, callback, | |
| 479 error_callback); | |
| 480 } | |
| 396 | 481 |
| 397 void ArcBluetoothBridge::OnDescriptorReadRequest( | 482 void ArcBluetoothBridge::OnDescriptorReadRequest( |
| 398 const BluetoothDevice* device, | 483 const BluetoothDevice* device, |
| 399 const BluetoothLocalGattDescriptor* descriptor, | 484 const BluetoothLocalGattDescriptor* descriptor, |
| 400 int offset, | 485 int offset, |
| 401 const ValueCallback& callback, | 486 const ValueCallback& callback, |
| 402 const ErrorCallback& error_callback) {} | 487 const ErrorCallback& error_callback) { |
| 488 OnGattAttributeReadRequest(device, descriptor, offset, callback, | |
| 489 error_callback); | |
| 490 } | |
| 403 | 491 |
| 404 void ArcBluetoothBridge::OnDescriptorWriteRequest( | 492 void ArcBluetoothBridge::OnDescriptorWriteRequest( |
| 405 const BluetoothDevice* device, | 493 const BluetoothDevice* device, |
| 406 const BluetoothLocalGattDescriptor* descriptor, | 494 const BluetoothLocalGattDescriptor* descriptor, |
| 407 const std::vector<uint8_t>& value, | 495 const std::vector<uint8_t>& value, |
| 408 int offset, | 496 int offset, |
| 409 const base::Closure& callback, | 497 const base::Closure& callback, |
| 410 const ErrorCallback& error_callback) {} | 498 const ErrorCallback& error_callback) { |
| 499 OnGattAttributeWriteRequest(device, descriptor, value, offset, callback, | |
| 500 error_callback); | |
| 501 } | |
| 411 | 502 |
| 412 void ArcBluetoothBridge::OnNotificationsStart( | 503 void ArcBluetoothBridge::OnNotificationsStart( |
| 413 const BluetoothDevice* device, | 504 const BluetoothDevice* device, |
| 414 const BluetoothLocalGattCharacteristic* characteristic) {} | 505 const BluetoothLocalGattCharacteristic* characteristic) {} |
| 415 | 506 |
| 416 void ArcBluetoothBridge::OnNotificationsStop( | 507 void ArcBluetoothBridge::OnNotificationsStop( |
| 417 const BluetoothDevice* device, | 508 const BluetoothDevice* device, |
| 418 const BluetoothLocalGattCharacteristic* characteristic) {} | 509 const BluetoothLocalGattCharacteristic* characteristic) {} |
| 419 | 510 |
| 420 void ArcBluetoothBridge::EnableAdapter(const EnableAdapterCallback& callback) { | 511 void ArcBluetoothBridge::EnableAdapter(const EnableAdapterCallback& callback) { |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1104 int32_t ArcBluetoothBridge::CreateGattAttributeHandle( | 1195 int32_t ArcBluetoothBridge::CreateGattAttributeHandle( |
| 1105 LocalGattAttribute* attribute) { | 1196 LocalGattAttribute* attribute) { |
| 1106 DCHECK(CalledOnValidThread()); | 1197 DCHECK(CalledOnValidThread()); |
| 1107 if (!attribute) | 1198 if (!attribute) |
| 1108 return kInvalidGattAttributeHandle; | 1199 return kInvalidGattAttributeHandle; |
| 1109 int32_t handle = GetNextGattServerAttributeHandle(); | 1200 int32_t handle = GetNextGattServerAttributeHandle(); |
| 1110 if (handle == kInvalidGattAttributeHandle) | 1201 if (handle == kInvalidGattAttributeHandle) |
| 1111 return kInvalidGattAttributeHandle; | 1202 return kInvalidGattAttributeHandle; |
| 1112 const std::string& identifier = attribute->GetIdentifier(); | 1203 const std::string& identifier = attribute->GetIdentifier(); |
| 1113 gatt_identifier_[handle] = identifier; | 1204 gatt_identifier_[handle] = identifier; |
| 1205 gatt_handle_[identifier] = handle; | |
| 1114 return handle; | 1206 return handle; |
| 1115 } | 1207 } |
| 1116 | 1208 |
| 1117 void ArcBluetoothBridge::AddService(mojom::BluetoothGattServiceIDPtr service_id, | 1209 void ArcBluetoothBridge::AddService(mojom::BluetoothGattServiceIDPtr service_id, |
| 1118 int32_t num_handles, | 1210 int32_t num_handles, |
| 1119 const AddServiceCallback& callback) { | 1211 const AddServiceCallback& callback) { |
| 1120 if (!IsGattServerAttributeHandleAvailable(num_handles)) { | 1212 if (!IsGattServerAttributeHandleAvailable(num_handles)) { |
| 1121 callback.Run(kInvalidGattAttributeHandle); | 1213 callback.Run(kInvalidGattAttributeHandle); |
| 1122 return; | 1214 return; |
| 1123 } | 1215 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1216 base::Bind(&OnGattOperationError, callback)); | 1308 base::Bind(&OnGattOperationError, callback)); |
| 1217 } | 1309 } |
| 1218 | 1310 |
| 1219 void ArcBluetoothBridge::DeleteService(int32_t service_handle, | 1311 void ArcBluetoothBridge::DeleteService(int32_t service_handle, |
| 1220 const DeleteServiceCallback& callback) { | 1312 const DeleteServiceCallback& callback) { |
| 1221 DCHECK(CalledOnValidThread()); | 1313 DCHECK(CalledOnValidThread()); |
| 1222 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end()); | 1314 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end()); |
| 1223 BluetoothLocalGattService* service = | 1315 BluetoothLocalGattService* service = |
| 1224 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]); | 1316 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]); |
| 1225 DCHECK(service); | 1317 DCHECK(service); |
| 1226 | 1318 gatt_identifier_.erase(service_handle); |
| 1319 gatt_handle_.erase(service->GetIdentifier()); | |
| 1227 service->Delete(); | 1320 service->Delete(); |
| 1228 gatt_identifier_.erase(service_handle); | |
| 1229 OnGattOperationDone(callback); | 1321 OnGattOperationDone(callback); |
| 1230 } | 1322 } |
| 1231 | 1323 |
| 1232 void ArcBluetoothBridge::SendIndication( | 1324 void ArcBluetoothBridge::SendIndication( |
| 1233 int32_t attribute_handle, | 1325 int32_t attribute_handle, |
| 1234 mojom::BluetoothAddressPtr address, | 1326 mojom::BluetoothAddressPtr address, |
| 1235 bool confirm, | 1327 bool confirm, |
| 1236 mojo::Array<uint8_t> value, | 1328 mojo::Array<uint8_t> value, |
| 1237 const SendIndicationCallback& callback) {} | 1329 const SendIndicationCallback& callback) {} |
| 1238 | 1330 |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1571 LOG(WARNING) << "Bluetooth instance is too old (version " << version | 1663 LOG(WARNING) << "Bluetooth instance is too old (version " << version |
| 1572 << ") need version " << version_need; | 1664 << ") need version " << version_need; |
| 1573 return false; | 1665 return false; |
| 1574 } | 1666 } |
| 1575 | 1667 |
| 1576 bool ArcBluetoothBridge::CalledOnValidThread() { | 1668 bool ArcBluetoothBridge::CalledOnValidThread() { |
| 1577 return thread_checker_.CalledOnValidThread(); | 1669 return thread_checker_.CalledOnValidThread(); |
| 1578 } | 1670 } |
| 1579 | 1671 |
| 1580 } // namespace arc | 1672 } // namespace arc |
| OLD | NEW |