Commit 702552c9 authored by mcchou's avatar mcchou Committed by Commit bot

arc: bluetooth: Add SDP host side support

This implements the Chrome side support for Service Discovery Protocol.
- Retrieve SDP records from a remote device
- Create/remove a SDP record for the local device
- Convert service record/attribute between Chrome and Mojo

BUG=b:29314637
TEST=None (The manual test is blocked on chromium:627907.)

Review-Url: https://codereview.chromium.org/2149713002
Cr-Commit-Position: refs/heads/master@{#417210}
parent e15391d9
......@@ -159,6 +159,7 @@ mojom("arc_bindings") {
]
deps = [
"//mojo/common:common_custom_types",
"//ui/gfx/geometry/mojo",
]
......
......@@ -28,6 +28,7 @@
#include "device/bluetooth/bluetooth_gatt_notify_session.h"
#include "device/bluetooth/bluetooth_local_gatt_characteristic.h"
#include "device/bluetooth/bluetooth_local_gatt_descriptor.h"
#include "device/bluetooth/bluez/bluetooth_device_bluez.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
......@@ -56,6 +57,7 @@ constexpr int32_t kMinBtleVersion = 1;
constexpr int32_t kMinBtleNotifyVersion = 2;
constexpr int32_t kMinGattServerVersion = 3;
constexpr int32_t kMinAddrChangeVersion = 4;
constexpr int32_t kMinSdpSupportVersion = 5;
constexpr uint32_t kGattReadPermission =
BluetoothGattCharacteristic::Permission::PERMISSION_READ |
BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
......@@ -77,11 +79,17 @@ constexpr int kMaxGattAttributeLength = 512;
// https://goo.gl/k7PM6u
constexpr uint16_t kAndroidMBluetoothVersionNumber = 95;
constexpr uint16_t kMaxAdvertisement = 5;
// Bluetooth SDP Service Class ID List Attribute identifier
constexpr uint16_t kServiceClassIDListAttributeID = 0x0001;
using GattStatusCallback =
base::Callback<void(arc::mojom::BluetoothGattStatus)>;
using GattReadCallback =
base::Callback<void(arc::mojom::BluetoothGattValuePtr)>;
using CreateSdpRecordCallback =
base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>;
using RemoveSdpRecordCallback =
base::Callback<void(arc::mojom::BluetoothStatus)>;
// Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
// Convert the last 4 characters of |identifier| to an
......@@ -194,6 +202,48 @@ mojo::Array<arc::mojom::BluetoothPropertyPtr> GetDiscoveryTimeoutProperty(
return properties;
}
void OnCreateServiceRecordDone(const CreateSdpRecordCallback& callback,
uint32_t service_handle) {
arc::mojom::BluetoothCreateSdpRecordResultPtr result =
arc::mojom::BluetoothCreateSdpRecordResult::New();
result->status = arc::mojom::BluetoothStatus::SUCCESS;
result->service_handle = service_handle;
callback.Run(std::move(result));
}
void OnCreateServiceRecordError(
const CreateSdpRecordCallback& callback,
bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) {
arc::mojom::BluetoothCreateSdpRecordResultPtr result =
arc::mojom::BluetoothCreateSdpRecordResult::New();
if (error_code ==
bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) {
result->status = arc::mojom::BluetoothStatus::NOT_READY;
} else {
result->status = arc::mojom::BluetoothStatus::FAIL;
}
callback.Run(std::move(result));
}
void OnRemoveServiceRecordDone(const RemoveSdpRecordCallback& callback) {
callback.Run(arc::mojom::BluetoothStatus::SUCCESS);
}
void OnRemoveServiceRecordError(
const RemoveSdpRecordCallback& callback,
bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) {
arc::mojom::BluetoothStatus status;
if (error_code ==
bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY)
status = arc::mojom::BluetoothStatus::NOT_READY;
else
status = arc::mojom::BluetoothStatus::FAIL;
callback.Run(status);
}
} // namespace
namespace arc {
......@@ -984,8 +1034,8 @@ void ArcBluetoothBridge::ConnectLEDevice(
return;
}
// Also pass disconnect callback in error case
// since it would be disconnected anyway.
// Also pass disconnect callback in error case since it would be disconnected
// anyway.
mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
device->CreateGattConnection(
base::Bind(&ArcBluetoothBridge::OnGattConnected,
......@@ -1483,6 +1533,54 @@ void ArcBluetoothBridge::SendIndication(
mojo::Array<uint8_t> value,
const SendIndicationCallback& callback) {}
void ArcBluetoothBridge::GetSdpRecords(mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothUUIDPtr target_uuid) {
BluetoothDevice* device =
bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
bluez::BluetoothDeviceBlueZ* device_bluez =
static_cast<bluez::BluetoothDeviceBlueZ*>(device);
mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
mojom::BluetoothUUIDPtr target_uuid_clone = target_uuid.Clone();
device_bluez->GetServiceRecords(
base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsDone,
weak_factory_.GetWeakPtr(), base::Passed(&remote_addr),
base::Passed(&target_uuid)),
base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsError,
weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone),
base::Passed(&target_uuid_clone)));
}
void ArcBluetoothBridge::CreateSdpRecord(
mojom::BluetoothSdpRecordPtr record_mojo,
const CreateSdpRecordCallback& callback) {
auto record = record_mojo.To<bluez::BluetoothServiceRecordBlueZ>();
// Check if ServiceClassIDList attribute (attribute ID 0x0001) is included
// after type conversion, since it is mandatory for creating a service record.
if (!record.IsAttributePresented(kServiceClassIDListAttributeID)) {
mojom::BluetoothCreateSdpRecordResultPtr result =
mojom::BluetoothCreateSdpRecordResult::New();
result->status = mojom::BluetoothStatus::FAIL;
callback.Run(std::move(result));
return;
}
bluetooth_adapter_->CreateServiceRecord(
record, base::Bind(&OnCreateServiceRecordDone, callback),
base::Bind(&OnCreateServiceRecordError, callback));
}
void ArcBluetoothBridge::RemoveSdpRecord(
uint32_t service_handle,
const RemoveSdpRecordCallback& callback) {
bluetooth_adapter_->RemoveServiceRecord(
service_handle, base::Bind(&OnRemoveServiceRecordDone, callback),
base::Bind(&OnRemoveServiceRecordError, callback));
}
void ArcBluetoothBridge::OnDiscoveryError() {
LOG(WARNING) << "failed to change discovery state";
}
......@@ -1826,8 +1924,7 @@ void ArcBluetoothBridge::SendCachedPairedDevices() const {
}
// OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING
// to
// make sure the bond state machine on Android is ready to take the
// to make sure the bond state machine on Android is ready to take the
// pair-done event. Otherwise the pair-done event will be dropped as an
// invalid change of paired status.
OnPairing(addr->Clone());
......@@ -1835,6 +1932,52 @@ void ArcBluetoothBridge::SendCachedPairedDevices() const {
}
}
void ArcBluetoothBridge::OnGetServiceRecordsDone(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothUUIDPtr target_uuid,
const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez) {
if (!CheckBluetoothInstanceVersion(kMinSdpSupportVersion))
return;
if (!HasBluetoothInstance())
return;
arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords(
mojom::BluetoothStatus::SUCCESS, std::move(remote_addr),
std::move(target_uuid),
mojo::Array<mojom::BluetoothSdpRecordPtr>::From(records_bluez));
}
void ArcBluetoothBridge::OnGetServiceRecordsError(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothUUIDPtr target_uuid,
bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) {
if (!HasBluetoothInstance())
return;
if (!CheckBluetoothInstanceVersion(kMinSdpSupportVersion))
return;
mojom::BluetoothStatus status;
switch (error_code) {
case bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY:
status = mojom::BluetoothStatus::NOT_READY;
break;
case bluez::BluetoothServiceRecordBlueZ::ErrorCode::
ERROR_DEVICE_DISCONNECTED:
status = mojom::BluetoothStatus::RMT_DEV_DOWN;
break;
default:
status = mojom::BluetoothStatus::FAIL;
break;
}
arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords(
status, std::move(remote_addr), std::move(target_uuid),
mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0));
}
bool ArcBluetoothBridge::CheckBluetoothInstanceVersion(
uint32_t version_need) const {
uint32_t version = arc_bridge_service()->bluetooth()->version();
......
......@@ -268,6 +268,14 @@ class ArcBluetoothBridge
mojo::Array<uint8_t> value,
const SendIndicationCallback& callback) override;
// Bluetooth Mojo host interface - Bluetooth SDP functions
void GetSdpRecords(mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothUUIDPtr target_uuid) override;
void CreateSdpRecord(mojom::BluetoothSdpRecordPtr record_mojo,
const CreateSdpRecordCallback& callback) override;
void RemoveSdpRecord(uint32_t service_handle,
const RemoveSdpRecordCallback& callback) override;
// Chrome observer callbacks
void OnPoweredOn(
const base::Callback<void(mojom::BluetoothAdapterState)>& callback) const;
......@@ -365,6 +373,15 @@ class ArcBluetoothBridge
void OnSetDiscoverable(bool discoverable, bool success, uint32_t timeout);
void SetDiscoverable(bool discoverable, uint32_t timeout);
void OnGetServiceRecordsDone(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothUUIDPtr target_uuid,
const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez);
void OnGetServiceRecordsError(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothUUIDPtr target_uuid,
bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code);
bool CalledOnValidThread();
mojo::Binding<mojom::BluetoothHost> binding_;
......
......@@ -7,6 +7,7 @@
#include "components/arc/common/bluetooth.mojom.h"
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.h"
namespace mojo {
......@@ -49,6 +50,49 @@ struct EnumTraits<arc::mojom::BluetoothDeviceType,
}
};
template <>
struct EnumTraits<arc::mojom::BluetoothSdpAttributeType,
bluez::BluetoothServiceAttributeValueBlueZ::Type> {
static arc::mojom::BluetoothSdpAttributeType ToMojom(
bluez::BluetoothServiceAttributeValueBlueZ::Type input) {
switch (input) {
case bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE:
case bluez::BluetoothServiceAttributeValueBlueZ::UINT:
case bluez::BluetoothServiceAttributeValueBlueZ::INT:
case bluez::BluetoothServiceAttributeValueBlueZ::UUID:
case bluez::BluetoothServiceAttributeValueBlueZ::STRING:
case bluez::BluetoothServiceAttributeValueBlueZ::BOOL:
case bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE:
case bluez::BluetoothServiceAttributeValueBlueZ::URL:
return static_cast<arc::mojom::BluetoothSdpAttributeType>(input);
default:
NOTREACHED() << "Invalid type: " << static_cast<uint32_t>(input);
return arc::mojom::BluetoothSdpAttributeType::NULLTYPE;
}
}
static bool FromMojom(
arc::mojom::BluetoothSdpAttributeType input,
bluez::BluetoothServiceAttributeValueBlueZ::Type* output) {
switch (input) {
case arc::mojom::BluetoothSdpAttributeType::NULLTYPE:
case arc::mojom::BluetoothSdpAttributeType::UINT:
case arc::mojom::BluetoothSdpAttributeType::INT:
case arc::mojom::BluetoothSdpAttributeType::UUID:
case arc::mojom::BluetoothSdpAttributeType::STRING:
case arc::mojom::BluetoothSdpAttributeType::BOOL:
case arc::mojom::BluetoothSdpAttributeType::SEQUENCE:
case arc::mojom::BluetoothSdpAttributeType::URL:
*output = static_cast<bluez::BluetoothServiceAttributeValueBlueZ::Type>(
input);
return true;
default:
NOTREACHED() << "Invalid type: " << static_cast<uint32_t>(input);
return false;
}
}
};
} // namespace mojo
#endif // COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_STRUCT_TRAITS_H_
......@@ -6,6 +6,7 @@
#include <cctype>
#include <iomanip>
#include <ios>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
......@@ -23,6 +24,13 @@ constexpr size_t kAddressSize = 6;
constexpr size_t kUUIDSize = 16;
constexpr char kInvalidAddress[] = "00:00:00:00:00:00";
// SDP Service attribute IDs.
constexpr uint16_t kServiceClassIDList = 0x0001;
constexpr uint16_t kProtocolDescriptorList = 0x0004;
constexpr uint16_t kBrowseGroupList = 0x0005;
constexpr uint16_t kBluetoothProfileDescriptorList = 0x0009;
constexpr uint16_t kServiceName = 0x0100;
bool IsNonHex(char c) {
return !isxdigit(c);
}
......@@ -150,4 +158,157 @@ TypeConverter<arc::mojom::BluetoothGattStatus,
return ret;
}
// static
arc::mojom::BluetoothSdpAttributePtr
TypeConverter<arc::mojom::BluetoothSdpAttributePtr,
bluez::BluetoothServiceAttributeValueBlueZ>::
Convert(const bluez::BluetoothServiceAttributeValueBlueZ& attr_bluez,
size_t depth) {
auto result = arc::mojom::BluetoothSdpAttribute::New();
result->type = attr_bluez.type();
result->type_size = 0;
switch (result->type) {
case bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE:
result->value.Append(base::Value::CreateNullValue());
break;
case bluez::BluetoothServiceAttributeValueBlueZ::UINT:
case bluez::BluetoothServiceAttributeValueBlueZ::INT:
case bluez::BluetoothServiceAttributeValueBlueZ::UUID:
case bluez::BluetoothServiceAttributeValueBlueZ::STRING:
case bluez::BluetoothServiceAttributeValueBlueZ::URL:
case bluez::BluetoothServiceAttributeValueBlueZ::BOOL:
result->type_size = attr_bluez.size();
result->value.Append(attr_bluez.value().CreateDeepCopy());
result->sequence =
mojo::Array<arc::mojom::BluetoothSdpAttributePtr>::New(0);
break;
case bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE:
if (depth + 1 >= arc::kBluetoothSDPMaxDepth) {
result->type = bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE;
result->type_size = 0;
result->value.Append(base::Value::CreateNullValue());
result->sequence =
mojo::Array<arc::mojom::BluetoothSdpAttributePtr>::New(0);
return result;
}
for (const auto& child : attr_bluez.sequence()) {
result->sequence.push_back(Convert(child, depth + 1));
}
result->type_size = result->sequence.size();
result->value.Clear();
break;
default:
NOTREACHED();
}
return result;
}
// static
bluez::BluetoothServiceAttributeValueBlueZ
TypeConverter<bluez::BluetoothServiceAttributeValueBlueZ,
arc::mojom::BluetoothSdpAttributePtr>::
Convert(const arc::mojom::BluetoothSdpAttributePtr& attr, size_t depth) {
bluez::BluetoothServiceAttributeValueBlueZ::Type type = attr->type;
switch (type) {
case bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE:
return bluez::BluetoothServiceAttributeValueBlueZ();
case bluez::BluetoothServiceAttributeValueBlueZ::UINT:
case bluez::BluetoothServiceAttributeValueBlueZ::INT:
case bluez::BluetoothServiceAttributeValueBlueZ::UUID:
case bluez::BluetoothServiceAttributeValueBlueZ::STRING:
case bluez::BluetoothServiceAttributeValueBlueZ::URL:
case bluez::BluetoothServiceAttributeValueBlueZ::BOOL: {
if (attr->value.GetSize() != 1) {
return bluez::BluetoothServiceAttributeValueBlueZ(
bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, 0,
base::Value::CreateNullValue());
}
std::unique_ptr<base::Value> value;
attr->value.Remove(0, &value);
return bluez::BluetoothServiceAttributeValueBlueZ(
type, static_cast<size_t>(attr->type_size), std::move(value));
}
case bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE: {
if (depth + 1 >= arc::kBluetoothSDPMaxDepth || attr->sequence.empty()) {
return bluez::BluetoothServiceAttributeValueBlueZ(
bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, 0,
base::Value::CreateNullValue());
}
auto bluez_sequence = base::MakeUnique<
bluez::BluetoothServiceAttributeValueBlueZ::Sequence>();
for (const auto& child : attr->sequence) {
bluez_sequence->push_back(Convert(child, depth + 1));
}
return bluez::BluetoothServiceAttributeValueBlueZ(
std::move(bluez_sequence));
break;
}
default:
NOTREACHED();
}
return bluez::BluetoothServiceAttributeValueBlueZ(
bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, 0,
base::Value::CreateNullValue());
}
// static
arc::mojom::BluetoothSdpRecordPtr
TypeConverter<arc::mojom::BluetoothSdpRecordPtr,
bluez::BluetoothServiceRecordBlueZ>::
Convert(const bluez::BluetoothServiceRecordBlueZ& record_bluez) {
arc::mojom::BluetoothSdpRecordPtr result =
arc::mojom::BluetoothSdpRecord::New();
for (auto id : record_bluez.GetAttributeIds()) {
switch (id) {
case kServiceClassIDList:
case kProtocolDescriptorList:
case kBrowseGroupList:
case kBluetoothProfileDescriptorList:
case kServiceName:
result->attrs[id] = arc::mojom::BluetoothSdpAttribute::From(
record_bluez.GetAttributeValue(id));
break;
default:
// Android does not support this.
break;
}
}
return result;
}
// static
bluez::BluetoothServiceRecordBlueZ
TypeConverter<bluez::BluetoothServiceRecordBlueZ,
arc::mojom::BluetoothSdpRecordPtr>::
Convert(const arc::mojom::BluetoothSdpRecordPtr& record) {
bluez::BluetoothServiceRecordBlueZ record_bluez;
for (const auto& pair : record->attrs) {
switch (pair.first) {
case kServiceClassIDList:
case kProtocolDescriptorList:
case kBrowseGroupList:
case kBluetoothProfileDescriptorList:
case kServiceName:
record_bluez.AddRecordEntry(
pair.first,
pair.second.To<bluez::BluetoothServiceAttributeValueBlueZ>());
break;
default:
NOTREACHED();
break;
}
}
return record_bluez;
}
} // namespace mojo
......@@ -12,12 +12,26 @@
#include "components/arc/common/bluetooth.mojom.h"
#include "device/bluetooth/bluetooth_gatt_service.h"
#include "device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.h"
#include "device/bluetooth/bluez/bluetooth_service_record_bluez.h"
#include "mojo/public/cpp/bindings/type_converter.h"
namespace device {
class BluetoothUUID;
}
namespace arc {
// The design of SDP attribute allows the attributes in the sequence of an
// attribute to be of sequence type. To prevent a malicious party from sending
// extremely deep attributes to cause the stack overflow, a maximum depth is
// enforced during the conversion between
// bluez::BluetoothServiceAttributeValueBlueZ and
// arc::mojom::BluetoothSdpAttributePtr. However, there is no assigned number
// defined in SDP specification, so we choose 32 as the limit based on the
// depths observed from various Bluetooth devices in the field.
constexpr size_t kBluetoothSDPMaxDepth = 32;
} // namespace arc
namespace mojo {
template <>
......@@ -49,6 +63,44 @@ struct TypeConverter<arc::mojom::BluetoothGattStatus,
const device::BluetoothGattService::GattErrorCode& error_code);
};
template <>
struct TypeConverter<arc::mojom::BluetoothSdpAttributePtr,
bluez::BluetoothServiceAttributeValueBlueZ> {
static arc::mojom::BluetoothSdpAttributePtr Convert(
const bluez::BluetoothServiceAttributeValueBlueZ& attr_bluez,
size_t depth);
static arc::mojom::BluetoothSdpAttributePtr Convert(
const bluez::BluetoothServiceAttributeValueBlueZ& attr_bluez) {
return Convert(attr_bluez, 0);
}
};
template <>
struct TypeConverter<bluez::BluetoothServiceAttributeValueBlueZ,
arc::mojom::BluetoothSdpAttributePtr> {
static bluez::BluetoothServiceAttributeValueBlueZ Convert(
const arc::mojom::BluetoothSdpAttributePtr& attr,
size_t depth);
static bluez::BluetoothServiceAttributeValueBlueZ Convert(
const arc::mojom::BluetoothSdpAttributePtr& attr) {
return Convert(attr, 0);
}
};
template <>
struct TypeConverter<arc::mojom::BluetoothSdpRecordPtr,
bluez::BluetoothServiceRecordBlueZ> {
static arc::mojom::BluetoothSdpRecordPtr Convert(
const bluez::BluetoothServiceRecordBlueZ& rcd_bluez);
};
template <>
struct TypeConverter<bluez::BluetoothServiceRecordBlueZ,
arc::mojom::BluetoothSdpRecordPtr> {
static bluez::BluetoothServiceRecordBlueZ Convert(
const arc::mojom::BluetoothSdpRecordPtr& rcd);
};
} // namespace mojo
#endif // COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_
......@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Next MinVersion: 5
// Next MinVersion: 6
module arc.mojom;
import "mojo/common/common_custom_types.mojom";
[Extensible]
enum BluetoothAdapterState {
OFF = 0,
......@@ -231,6 +233,44 @@ struct BluetoothGattDBElement {
uint8 properties;
};
// Bluetooth SDP types
[Extensible]
enum BluetoothSdpAttributeType {
NULLTYPE = 0,
UINT,
INT,
UUID,
STRING,
BOOL,
SEQUENCE,
URL,
};
/*
* A BluetoothSdpAttribute contains either a value or a sequence, where a
* sequence is an array of BluetoothSdpAttribute. A multi-layered attribute
* design is intended. Note BluetoothSdpAttribute supports up to depth 32 for
* the attribute with multi-layer sequences. The attributes within a sequence
* which has the depth beyond the maximum supported depth will be invalidated
* and ignored.
*/
struct BluetoothSdpAttribute {
BluetoothSdpAttributeType type;
uint32 type_size;
mojo.common.mojom.ListValue value;
array<BluetoothSdpAttribute> sequence;
};
struct BluetoothSdpRecord {
map<uint16, BluetoothSdpAttribute> attrs;
};
struct BluetoothCreateSdpRecordResult {
BluetoothStatus status;
uint32 service_handle;
};
// Next Method ID: 40
interface BluetoothHost {
EnableAdapter@0() => (BluetoothAdapterState state);
DisableAdapter@1() => (BluetoothAdapterState state);
......@@ -322,9 +362,17 @@ interface BluetoothHost {
bool confirm,
array<uint8> value)
=> (BluetoothGattStatus status);
// Bluetooth SDP functions
[MinVersion=5] GetSdpRecords@37(BluetoothAddress remote_addr,
BluetoothUUID target_uuid);
[MinVersion=5] CreateSdpRecord@38(BluetoothSdpRecord record)
=> (BluetoothCreateSdpRecordResult result);
[MinVersion=5] RemoveSdpRecord@39(uint32 service_handle)
=> (BluetoothStatus status);
};
// Next Method ID: 17
// Next Method ID: 18
interface BluetoothInstance {
Init@0(BluetoothHost host_ptr);
......@@ -376,4 +424,10 @@ interface BluetoothInstance {
int32 offset,
array<uint8> value)
=> (BluetoothGattStatus status);
// Bluetooth SDP function
[MinVersion=5] OnGetSdpRecords@17(BluetoothStatus status,
BluetoothAddress remove_addr,
BluetoothUUID target_uuid,
array<BluetoothSdpRecord> records);
};
mojom = "//components/arc/common/bluetooth.mojom"
public_headers = [ "//device/bluetooth/bluetooth_common.h" ]
public_headers = [
"//device/bluetooth/bluetooth_common.h",
"//device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.h",
]
traits_headers = [ "//components/arc/bluetooth/bluetooth_struct_traits.h" ]
deps = [
"//device/bluetooth",
]
type_mappings = [ "arc.mojom.BluetoothDeviceType=device::BluetoothTransport" ]
type_mappings = [
"arc.mojom.BluetoothDeviceType=device::BluetoothTransport",
"arc.mojom.BluetoothSdpAttributeType=bluez::BluetoothServiceAttributeValueBlueZ::Type",
]
......@@ -112,4 +112,10 @@ void FakeBluetoothInstance::RequestGattWrite(
mojo::Array<uint8_t> value,
const RequestGattWriteCallback& callback) {}
void FakeBluetoothInstance::OnGetSdpRecords(
mojom::BluetoothStatus status,
mojom::BluetoothAddressPtr remove_addr,
mojom::BluetoothUUIDPtr target_uuid,
mojo::Array<mojom::BluetoothSdpRecordPtr> records) {}
} // namespace arc
......@@ -120,6 +120,12 @@ class FakeBluetoothInstance : public mojom::BluetoothInstance {
mojo::Array<uint8_t> value,
const RequestGattWriteCallback& callback) override;
void OnGetSdpRecords(
mojom::BluetoothStatus status,
mojom::BluetoothAddressPtr remove_addr,
mojom::BluetoothUUIDPtr target_uuid,
mojo::Array<mojom::BluetoothSdpRecordPtr> records) override;
const std::vector<mojo::Array<mojom::BluetoothPropertyPtr>>&
device_found_data() const {
return device_found_data_;
......
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