1 // Copyright 2013 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. 4 5 #include "device/bluetooth/bluetooth_device_mac.h" 6 7 #include <IOBluetooth/Bluetooth.h> 8 #import <IOBluetooth/objc/IOBluetoothDevice.h> 9 #import <IOBluetooth/objc/IOBluetoothSDPServiceRecord.h> 10 #import <IOBluetooth/objc/IOBluetoothSDPUUID.h> 11 12 #include <string> 13 14 #include "base/basictypes.h" 15 #include "base/hash.h" 16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/stringprintf.h" 18 #include "base/strings/sys_string_conversions.h" 19 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" 20 #include "device/bluetooth/bluetooth_profile_mac.h" 21 #include "device/bluetooth/bluetooth_service_record_mac.h" 22 #include "device/bluetooth/bluetooth_socket_mac.h" 23 24 // Replicate specific 10.7 SDK declarations for building with prior SDKs. 25 #if !defined(MAC_OS_X_VERSION_10_7) || \ 26 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 27 28 @interface IOBluetoothDevice (LionSDKDeclarations) 29 - (NSString*)addressString; 30 - (NSString*)name; 31 - (unsigned int)classOfDevice; 32 - (NSArray*)services; 33 @end 34 35 #endif // MAC_OS_X_VERSION_10_7 36 37 namespace { 38 39 // Converts |uuid| to a IOBluetoothSDPUUID instance. 40 // 41 // |uuid| must be in the format of XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. 42 IOBluetoothSDPUUID* GetIOBluetoothSDPUUID(const std::string& uuid) { 43 DCHECK(uuid.size() == 36); 44 DCHECK(uuid[8] == '-'); 45 DCHECK(uuid[13] == '-'); 46 DCHECK(uuid[18] == '-'); 47 DCHECK(uuid[23] == '-'); 48 std::string numbers_only = uuid; 49 numbers_only.erase(23, 1); 50 numbers_only.erase(18, 1); 51 numbers_only.erase(13, 1); 52 numbers_only.erase(8, 1); 53 std::vector<uint8> uuid_bytes_vector; 54 base::HexStringToBytes(numbers_only, &uuid_bytes_vector); 55 DCHECK(uuid_bytes_vector.size() == 16); 56 57 return [IOBluetoothSDPUUID uuidWithBytes:&uuid_bytes_vector[0] 58 length:uuid_bytes_vector.size()]; 59 } 60 61 } // namespace 62 63 namespace device { 64 65 BluetoothDeviceMac::BluetoothDeviceMac(IOBluetoothDevice* device) 66 : BluetoothDevice(), device_([device retain]) { 67 } 68 69 BluetoothDeviceMac::~BluetoothDeviceMac() { 70 [device_ release]; 71 } 72 73 uint32 BluetoothDeviceMac::GetBluetoothClass() const { 74 return [device_ classOfDevice]; 75 } 76 77 std::string BluetoothDeviceMac::GetDeviceName() const { 78 return base::SysNSStringToUTF8([device_ name]); 79 } 80 81 std::string BluetoothDeviceMac::GetAddress() const { 82 return base::SysNSStringToUTF8([device_ addressString]); 83 } 84 85 uint16 BluetoothDeviceMac::GetVendorID() const { 86 return 0; 87 } 88 89 uint16 BluetoothDeviceMac::GetProductID() const { 90 return 0; 91 } 92 93 uint16 BluetoothDeviceMac::GetDeviceID() const { 94 return 0; 95 } 96 97 bool BluetoothDeviceMac::IsPaired() const { 98 return [device_ isPaired]; 99 } 100 101 bool BluetoothDeviceMac::IsConnected() const { 102 return [device_ isConnected]; 103 } 104 105 bool BluetoothDeviceMac::IsConnectable() const { 106 return false; 107 } 108 109 bool BluetoothDeviceMac::IsConnecting() const { 110 return false; 111 } 112 113 // TODO(youngki): BluetoothServiceRecord is deprecated; implement this method 114 // without using BluetoothServiceRecord. 115 BluetoothDevice::ServiceList BluetoothDeviceMac::GetServices() const { 116 ServiceList service_uuids; 117 for (IOBluetoothSDPServiceRecord* service in [device_ services]) { 118 BluetoothServiceRecordMac service_record(service); 119 service_uuids.push_back(service_record.uuid()); 120 } 121 return service_uuids; 122 } 123 124 // NOTE(youngki): This method is deprecated; it will be removed soon. 125 void BluetoothDeviceMac::GetServiceRecords( 126 const ServiceRecordsCallback& callback, 127 const ErrorCallback& error_callback) { 128 ServiceRecordList service_record_list; 129 for (IOBluetoothSDPServiceRecord* service in [device_ services]) { 130 BluetoothServiceRecord* service_record = 131 new BluetoothServiceRecordMac(service); 132 service_record_list.push_back(service_record); 133 } 134 135 callback.Run(service_record_list); 136 } 137 138 // NOTE(youngki): This method is deprecated; it will be removed soon. 139 void BluetoothDeviceMac::ProvidesServiceWithName( 140 const std::string& name, 141 const ProvidesServiceCallback& callback) { 142 NOTIMPLEMENTED(); 143 callback.Run(false); 144 } 145 146 bool BluetoothDeviceMac::ExpectingPinCode() const { 147 NOTIMPLEMENTED(); 148 return false; 149 } 150 151 bool BluetoothDeviceMac::ExpectingPasskey() const { 152 NOTIMPLEMENTED(); 153 return false; 154 } 155 156 bool BluetoothDeviceMac::ExpectingConfirmation() const { 157 NOTIMPLEMENTED(); 158 return false; 159 } 160 161 void BluetoothDeviceMac::Connect( 162 PairingDelegate* pairing_delegate, 163 const base::Closure& callback, 164 const ConnectErrorCallback& error_callback) { 165 NOTIMPLEMENTED(); 166 } 167 168 void BluetoothDeviceMac::SetPinCode(const std::string& pincode) { 169 NOTIMPLEMENTED(); 170 } 171 172 void BluetoothDeviceMac::SetPasskey(uint32 passkey) { 173 NOTIMPLEMENTED(); 174 } 175 176 void BluetoothDeviceMac::ConfirmPairing() { 177 NOTIMPLEMENTED(); 178 } 179 180 void BluetoothDeviceMac::RejectPairing() { 181 NOTIMPLEMENTED(); 182 } 183 184 void BluetoothDeviceMac::CancelPairing() { 185 NOTIMPLEMENTED(); 186 } 187 188 void BluetoothDeviceMac::Disconnect( 189 const base::Closure& callback, 190 const ErrorCallback& error_callback) { 191 NOTIMPLEMENTED(); 192 } 193 194 void BluetoothDeviceMac::Forget(const ErrorCallback& error_callback) { 195 NOTIMPLEMENTED(); 196 } 197 198 void BluetoothDeviceMac::ConnectToService( 199 const std::string& service_uuid, 200 const SocketCallback& callback) { 201 IOBluetoothSDPServiceRecord* record = 202 [device_ getServiceRecordForUUID:GetIOBluetoothSDPUUID(service_uuid)]; 203 if (record != nil) { 204 BluetoothServiceRecordMac service_record(record); 205 scoped_refptr<BluetoothSocket> socket( 206 BluetoothSocketMac::CreateBluetoothSocket(service_record)); 207 if (socket.get() != NULL) 208 callback.Run(socket); 209 } 210 } 211 212 void BluetoothDeviceMac::ConnectToProfile( 213 device::BluetoothProfile* profile, 214 const base::Closure& callback, 215 const ErrorCallback& error_callback) { 216 if (static_cast<BluetoothProfileMac*>(profile)->Connect(device_)) 217 callback.Run(); 218 else 219 error_callback.Run(); 220 } 221 222 void BluetoothDeviceMac::SetOutOfBandPairingData( 223 const BluetoothOutOfBandPairingData& data, 224 const base::Closure& callback, 225 const ErrorCallback& error_callback) { 226 NOTIMPLEMENTED(); 227 } 228 229 void BluetoothDeviceMac::ClearOutOfBandPairingData( 230 const base::Closure& callback, 231 const ErrorCallback& error_callback) { 232 NOTIMPLEMENTED(); 233 } 234 235 } // namespace device 236