Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / device / bluetooth / bluetooth_low_energy_device_mac.mm
blobf81fdf7ba745480d662a37c7308d9a3b663a882f
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "device/bluetooth/bluetooth_low_energy_device_mac.h"
7 #import <CoreFoundation/CoreFoundation.h>
9 #include "base/mac/mac_util.h"
10 #include "base/mac/scoped_cftyperef.h"
11 #include "base/mac/sdk_forward_declarations.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/sys_string_conversions.h"
14 #include "device/bluetooth/bluetooth_adapter_mac.h"
15 #include "device/bluetooth/bluetooth_device.h"
17 using device::BluetoothDevice;
18 using device::BluetoothLowEnergyDeviceMac;
20 namespace {
22 // Converts a CBUUID to a BluetoothUUID.
23 device::BluetoothUUID BluetoothUUIDWithCBUUID(CBUUID* uuid) {
24   // UUIDString only available OS X >= 10.8.
25   DCHECK(base::mac::IsOSMountainLionOrLater());
26   std::string uuid_c_string = base::SysNSStringToUTF8([uuid UUIDString]);
27   return device::BluetoothUUID(uuid_c_string);
30 }  // namespace
32 BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac(
33     CBPeripheral* peripheral,
34     NSDictionary* advertisement_data,
35     int rssi) {
36   DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable());
37   identifier_ = GetPeripheralIdentifier(peripheral);
38   hash_address_ = GetPeripheralHashAddress(peripheral);
39   Update(peripheral, advertisement_data, rssi);
42 BluetoothLowEnergyDeviceMac::~BluetoothLowEnergyDeviceMac() {
45 void BluetoothLowEnergyDeviceMac::Update(CBPeripheral* peripheral,
46                                          NSDictionary* advertisement_data,
47                                          int rssi) {
48   last_update_time_.reset([[NSDate date] retain]);
49   peripheral_.reset([peripheral retain]);
50   rssi_ = rssi;
51   NSNumber* connectable =
52       [advertisement_data objectForKey:CBAdvertisementDataIsConnectable];
53   connectable_ = [connectable boolValue];
54   ClearServiceData();
55   NSDictionary* service_data =
56       [advertisement_data objectForKey:CBAdvertisementDataServiceDataKey];
57   for (CBUUID* uuid in service_data) {
58     NSData* data = [service_data objectForKey:uuid];
59     BluetoothUUID service_uuid = BluetoothUUIDWithCBUUID(uuid);
60     SetServiceData(service_uuid, static_cast<const char*>([data bytes]),
61                    [data length]);
62   }
63   NSArray* service_uuids =
64       [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey];
65   for (CBUUID* uuid in service_uuids) {
66     advertised_uuids_.insert(
67         BluetoothUUID(std::string([[uuid UUIDString] UTF8String])));
68   }
69   NSArray* overflow_service_uuids = [advertisement_data
70       objectForKey:CBAdvertisementDataOverflowServiceUUIDsKey];
71   for (CBUUID* uuid in overflow_service_uuids) {
72     advertised_uuids_.insert(
73         BluetoothUUID(std::string([[uuid UUIDString] UTF8String])));
74   }
77 std::string BluetoothLowEnergyDeviceMac::GetIdentifier() const {
78   return identifier_;
81 uint32 BluetoothLowEnergyDeviceMac::GetBluetoothClass() const {
82   return 0x1F00;  // Unspecified Device Class
85 std::string BluetoothLowEnergyDeviceMac::GetAddress() const {
86   return hash_address_;
89 BluetoothDevice::VendorIDSource BluetoothLowEnergyDeviceMac::GetVendorIDSource()
90     const {
91   return VENDOR_ID_UNKNOWN;
94 uint16 BluetoothLowEnergyDeviceMac::GetVendorID() const {
95   return 0;
98 uint16 BluetoothLowEnergyDeviceMac::GetProductID() const {
99   return 0;
102 uint16 BluetoothLowEnergyDeviceMac::GetDeviceID() const {
103   return 0;
106 int BluetoothLowEnergyDeviceMac::GetRSSI() const {
107   return rssi_;
110 bool BluetoothLowEnergyDeviceMac::IsPaired() const {
111   return false;
114 bool BluetoothLowEnergyDeviceMac::IsConnected() const {
115   return (GetPeripheralState() == CBPeripheralStateConnected);
118 bool BluetoothLowEnergyDeviceMac::IsConnectable() const {
119   return connectable_;
122 bool BluetoothLowEnergyDeviceMac::IsConnecting() const {
123   return false;
126 BluetoothDevice::UUIDList BluetoothLowEnergyDeviceMac::GetUUIDs() const {
127   return BluetoothDevice::UUIDList(advertised_uuids_.begin(),
128                                    advertised_uuids_.end());
131 int16 BluetoothLowEnergyDeviceMac::GetInquiryRSSI() const {
132   return kUnknownPower;
135 int16 BluetoothLowEnergyDeviceMac::GetInquiryTxPower() const {
136   NOTIMPLEMENTED();
137   return kUnknownPower;
140 bool BluetoothLowEnergyDeviceMac::ExpectingPinCode() const {
141   return false;
144 bool BluetoothLowEnergyDeviceMac::ExpectingPasskey() const {
145   return false;
148 bool BluetoothLowEnergyDeviceMac::ExpectingConfirmation() const {
149   return false;
152 void BluetoothLowEnergyDeviceMac::GetConnectionInfo(
153     const ConnectionInfoCallback& callback) {
154   NOTIMPLEMENTED();
157 void BluetoothLowEnergyDeviceMac::Connect(
158     PairingDelegate* pairing_delegate,
159     const base::Closure& callback,
160     const ConnectErrorCallback& error_callback) {
161   NOTIMPLEMENTED();
164 void BluetoothLowEnergyDeviceMac::SetPinCode(const std::string& pincode) {
165   NOTIMPLEMENTED();
168 void BluetoothLowEnergyDeviceMac::SetPasskey(uint32 passkey) {
169   NOTIMPLEMENTED();
172 void BluetoothLowEnergyDeviceMac::ConfirmPairing() {
173   NOTIMPLEMENTED();
176 void BluetoothLowEnergyDeviceMac::RejectPairing() {
177   NOTIMPLEMENTED();
180 void BluetoothLowEnergyDeviceMac::CancelPairing() {
181   NOTIMPLEMENTED();
184 void BluetoothLowEnergyDeviceMac::Disconnect(
185     const base::Closure& callback,
186     const ErrorCallback& error_callback) {
187   NOTIMPLEMENTED();
190 void BluetoothLowEnergyDeviceMac::Forget(const ErrorCallback& error_callback) {
191   NOTIMPLEMENTED();
194 void BluetoothLowEnergyDeviceMac::ConnectToService(
195     const BluetoothUUID& uuid,
196     const ConnectToServiceCallback& callback,
197     const ConnectToServiceErrorCallback& error_callback) {
198   NOTIMPLEMENTED();
201 void BluetoothLowEnergyDeviceMac::ConnectToServiceInsecurely(
202     const device::BluetoothUUID& uuid,
203     const ConnectToServiceCallback& callback,
204     const ConnectToServiceErrorCallback& error_callback) {
205   NOTIMPLEMENTED();
208 void BluetoothLowEnergyDeviceMac::CreateGattConnection(
209     const GattConnectionCallback& callback,
210     const ConnectErrorCallback& error_callback) {
211   NOTIMPLEMENTED();
214 NSDate* BluetoothLowEnergyDeviceMac::GetLastUpdateTime() const {
215   return last_update_time_.get();
218 std::string BluetoothLowEnergyDeviceMac::GetDeviceName() const {
219   return base::SysNSStringToUTF8([peripheral_ name]);
222 // static
223 std::string BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(
224     CBPeripheral* peripheral) {
225   DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable());
226   NSUUID* uuid = [peripheral identifier];
227   NSString* uuidString = [uuid UUIDString];
228   return base::SysNSStringToUTF8(uuidString);
231 // static
232 std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(
233     CBPeripheral* peripheral) {
234   const size_t kCanonicalAddressNumberOfBytes = 6;
235   char raw[kCanonicalAddressNumberOfBytes];
236   crypto::SHA256HashString(GetPeripheralIdentifier(peripheral), raw,
237                            sizeof(raw));
238   std::string hash = base::HexEncode(raw, sizeof(raw));
239   return BluetoothDevice::CanonicalizeAddress(hash);
242 CBPeripheralState BluetoothLowEnergyDeviceMac::GetPeripheralState() const {
243   Class peripheral_class = NSClassFromString(@"CBPeripheral");
244   base::scoped_nsobject<NSMethodSignature> signature([[peripheral_class
245       instanceMethodSignatureForSelector:@selector(state)] retain]);
246   base::scoped_nsobject<NSInvocation> invocation(
247       [[NSInvocation invocationWithMethodSignature:signature] retain]);
248   [invocation setTarget:peripheral_];
249   [invocation setSelector:@selector(state)];
250   [invocation invoke];
251   CBPeripheralState state = CBPeripheralStateDisconnected;
252   [invocation getReturnValue:&state];
253   return state;