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.
5 #include "device/bluetooth/bluetooth_device_mac.h"
9 #include "base/basictypes.h"
10 #include "base/hash.h"
11 #include "base/sequenced_task_runner.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/sys_string_conversions.h"
16 #include "device/bluetooth/bluetooth_profile_mac.h"
17 #include "device/bluetooth/bluetooth_service_record_mac.h"
18 #include "device/bluetooth/bluetooth_socket_mac.h"
19 #include "device/bluetooth/bluetooth_uuid.h"
21 // Replicate specific 10.7 SDK declarations for building with prior SDKs.
22 #if !defined(MAC_OS_X_VERSION_10_7) || \
23 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
25 @interface IOBluetoothDevice (LionSDKDeclarations)
26 - (NSString*)addressString;
27 - (unsigned int)classOfDevice;
28 - (BluetoothConnectionHandle)connectionHandle;
29 - (BluetoothHCIRSSIValue)rawRSSI;
33 #endif // MAC_OS_X_VERSION_10_7
35 // Undocumented API for accessing the Bluetooth transmit power level.
36 // Similar to the API defined here [ http://goo.gl/20Q5vE ].
37 @interface IOBluetoothHostController (UndocumentedAPI)
39 BluetoothHCIReadTransmitPowerLevel:(BluetoothConnectionHandle)connection
40 inType:(BluetoothHCITransmitPowerLevelType)type
41 outTransmitPowerLevel:(BluetoothHCITransmitPowerLevel*)level;
46 BluetoothDeviceMac::BluetoothDeviceMac(IOBluetoothDevice* device)
47 : device_([device retain]) {
50 BluetoothDeviceMac::~BluetoothDeviceMac() {
53 void BluetoothDeviceMac::AddObserver(
54 device::BluetoothDevice::Observer* observer) {
56 observers_.AddObserver(observer);
59 void BluetoothDeviceMac::RemoveObserver(
60 device::BluetoothDevice::Observer* observer) {
62 observers_.RemoveObserver(observer);
65 uint32 BluetoothDeviceMac::GetBluetoothClass() const {
66 return [device_ classOfDevice];
69 std::string BluetoothDeviceMac::GetDeviceName() const {
70 return base::SysNSStringToUTF8([device_ name]);
73 std::string BluetoothDeviceMac::GetAddress() const {
74 return GetDeviceAddress(device_);
77 BluetoothDevice::VendorIDSource BluetoothDeviceMac::GetVendorIDSource() const {
78 return VENDOR_ID_UNKNOWN;
81 uint16 BluetoothDeviceMac::GetVendorID() const {
85 uint16 BluetoothDeviceMac::GetProductID() const {
89 uint16 BluetoothDeviceMac::GetDeviceID() const {
93 int BluetoothDeviceMac::GetRSSI() const {
94 if (![device_ isConnected]) {
99 int rssi = [device_ rawRSSI];
101 // The API guarantees that +127 is returned in case the RSSI is not readable:
102 // http://goo.gl/bpURYv
104 return kUnknownPower;
109 int BluetoothDeviceMac::GetCurrentHostTransmitPower() const {
110 return GetHostTransmitPower(kReadCurrentTransmitPowerLevel);
113 int BluetoothDeviceMac::GetMaximumHostTransmitPower() const {
114 return GetHostTransmitPower(kReadMaximumTransmitPowerLevel);
117 bool BluetoothDeviceMac::IsPaired() const {
118 return [device_ isPaired];
121 bool BluetoothDeviceMac::IsConnected() const {
122 return [device_ isConnected];
125 bool BluetoothDeviceMac::IsConnectable() const {
129 bool BluetoothDeviceMac::IsConnecting() const {
133 // TODO(keybuk): BluetoothServiceRecord is deprecated; implement this method
134 // without using BluetoothServiceRecord.
135 BluetoothDevice::UUIDList BluetoothDeviceMac::GetUUIDs() const {
137 for (IOBluetoothSDPServiceRecord* service in [device_ services]) {
138 BluetoothServiceRecordMac service_record(service);
139 uuids.push_back(service_record.uuid());
144 bool BluetoothDeviceMac::ExpectingPinCode() const {
149 bool BluetoothDeviceMac::ExpectingPasskey() const {
154 bool BluetoothDeviceMac::ExpectingConfirmation() const {
159 void BluetoothDeviceMac::Connect(
160 PairingDelegate* pairing_delegate,
161 const base::Closure& callback,
162 const ConnectErrorCallback& error_callback) {
166 void BluetoothDeviceMac::SetPinCode(const std::string& pincode) {
170 void BluetoothDeviceMac::SetPasskey(uint32 passkey) {
174 void BluetoothDeviceMac::ConfirmPairing() {
178 void BluetoothDeviceMac::RejectPairing() {
182 void BluetoothDeviceMac::CancelPairing() {
186 void BluetoothDeviceMac::Disconnect(const base::Closure& callback,
187 const ErrorCallback& error_callback) {
191 void BluetoothDeviceMac::Forget(const ErrorCallback& error_callback) {
195 void BluetoothDeviceMac::ConnectToProfile(
196 BluetoothProfile* profile,
197 const base::Closure& callback,
198 const ConnectToProfileErrorCallback& error_callback) {
199 static_cast<BluetoothProfileMac*>(profile)
200 ->Connect(device_, callback, error_callback);
203 void BluetoothDeviceMac::ConnectToService(
204 const BluetoothUUID& uuid,
205 const ConnectToServiceCallback& callback,
206 const ConnectToServiceErrorCallback& error_callback) {
207 // TODO(keybuk): implement
211 void BluetoothDeviceMac::StartConnectionMonitor(
212 const base::Closure& callback,
213 const ErrorCallback& error_callback) {
217 int BluetoothDeviceMac::GetHostTransmitPower(
218 BluetoothHCITransmitPowerLevelType power_level_type) const {
219 IOBluetoothHostController* controller =
220 [IOBluetoothHostController defaultController];
222 // Bail if the undocumented API is unavailable on this machine.
223 SEL selector = @selector(
224 BluetoothHCIReadTransmitPowerLevel:inType:outTransmitPowerLevel:);
225 if (![controller respondsToSelector:selector])
226 return kUnknownPower;
228 BluetoothHCITransmitPowerLevel power_level;
230 [controller BluetoothHCIReadTransmitPowerLevel:[device_ connectionHandle]
231 inType:power_level_type
232 outTransmitPowerLevel:&power_level];
233 if (result != kIOReturnSuccess)
234 return kUnknownPower;
240 std::string BluetoothDeviceMac::GetDeviceAddress(IOBluetoothDevice* device) {
241 return CanonicalizeAddress(base::SysNSStringToUTF8([device addressString]));
244 } // namespace device