Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / device / bluetooth / bluetooth_classic_device_mac.mm
blobe524e8123db2493213c76c6c6977c74d03b97788
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_classic_device_mac.h"
7 #include <string>
9 #include "base/basictypes.h"
10 #include "base/bind.h"
11 #include "base/hash.h"
12 #include "base/mac/sdk_forward_declarations.h"
13 #include "base/sequenced_task_runner.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/sys_string_conversions.h"
17 #include "device/bluetooth/bluetooth_socket_mac.h"
18 #include "device/bluetooth/bluetooth_uuid.h"
20 // Undocumented API for accessing the Bluetooth transmit power level.
21 // Similar to the API defined here [ http://goo.gl/20Q5vE ].
22 @interface IOBluetoothHostController (UndocumentedAPI)
23 - (IOReturn)
24     BluetoothHCIReadTransmitPowerLevel:(BluetoothConnectionHandle)connection
25                                 inType:(BluetoothHCITransmitPowerLevelType)type
26                  outTransmitPowerLevel:(BluetoothHCITransmitPowerLevel*)level;
27 @end
29 namespace device {
30 namespace {
32 const char kApiUnavailable[] = "This API is not implemented on this platform.";
34 // Returns the first (should be, only) UUID contained within the
35 // |service_class_data|. Returns an invalid (empty) UUID if none is found.
36 BluetoothUUID ExtractUuid(IOBluetoothSDPDataElement* service_class_data) {
37   NSArray* inner_elements = [service_class_data getArrayValue];
38   IOBluetoothSDPUUID* sdp_uuid = nil;
39   for (IOBluetoothSDPDataElement* inner_element in inner_elements) {
40     if ([inner_element getTypeDescriptor] == kBluetoothSDPDataElementTypeUUID) {
41       sdp_uuid = [[inner_element getUUIDValue] getUUIDWithLength:16];
42       break;
43     }
44   }
46   if (!sdp_uuid)
47     return BluetoothUUID();
49   const uint8* uuid_bytes = reinterpret_cast<const uint8*>([sdp_uuid bytes]);
50   std::string uuid_str = base::HexEncode(uuid_bytes, 16);
51   DCHECK_EQ(uuid_str.size(), 32U);
52   uuid_str.insert(8, "-");
53   uuid_str.insert(13, "-");
54   uuid_str.insert(18, "-");
55   uuid_str.insert(23, "-");
56   return BluetoothUUID(uuid_str);
59 }  // namespace
61 BluetoothClassicDeviceMac::BluetoothClassicDeviceMac(
62     BluetoothAdapterMac* adapter,
63     IOBluetoothDevice* device)
64     : BluetoothDeviceMac(adapter), device_([device retain]) {}
66 BluetoothClassicDeviceMac::~BluetoothClassicDeviceMac() {
69 uint32 BluetoothClassicDeviceMac::GetBluetoothClass() const {
70   return [device_ classOfDevice];
73 std::string BluetoothClassicDeviceMac::GetDeviceName() const {
74   return base::SysNSStringToUTF8([device_ name]);
77 void BluetoothClassicDeviceMac::CreateGattConnectionImpl() {
78   // Classic devices do not support GATT connection.
79   DidFailToConnectGatt(ERROR_UNSUPPORTED_DEVICE);
82 void BluetoothClassicDeviceMac::DisconnectGatt() {}
84 std::string BluetoothClassicDeviceMac::GetAddress() const {
85   return GetDeviceAddress(device_);
88 BluetoothDevice::VendorIDSource BluetoothClassicDeviceMac::GetVendorIDSource()
89     const {
90   return VENDOR_ID_UNKNOWN;
93 uint16 BluetoothClassicDeviceMac::GetVendorID() const {
94   return 0;
97 uint16 BluetoothClassicDeviceMac::GetProductID() const {
98   return 0;
101 uint16 BluetoothClassicDeviceMac::GetDeviceID() const {
102   return 0;
105 bool BluetoothClassicDeviceMac::IsPaired() const {
106   return [device_ isPaired];
109 bool BluetoothClassicDeviceMac::IsConnected() const {
110   return [device_ isConnected];
113 bool BluetoothClassicDeviceMac::IsGattConnected() const {
114   return false;  // Classic devices do not support GATT connection.
117 bool BluetoothClassicDeviceMac::IsConnectable() const {
118   return false;
121 bool BluetoothClassicDeviceMac::IsConnecting() const {
122   return false;
125 BluetoothDevice::UUIDList BluetoothClassicDeviceMac::GetUUIDs() const {
126   UUIDList uuids;
127   for (IOBluetoothSDPServiceRecord* service_record in [device_ services]) {
128     IOBluetoothSDPDataElement* service_class_data =
129         [service_record getAttributeDataElement:
130                             kBluetoothSDPAttributeIdentifierServiceClassIDList];
131     if ([service_class_data getTypeDescriptor] ==
132         kBluetoothSDPDataElementTypeDataElementSequence) {
133       BluetoothUUID uuid = ExtractUuid(service_class_data);
134       if (uuid.IsValid())
135         uuids.push_back(uuid);
136     }
137   }
138   return uuids;
141 int16 BluetoothClassicDeviceMac::GetInquiryRSSI() const {
142   return kUnknownPower;
145 int16 BluetoothClassicDeviceMac::GetInquiryTxPower() const {
146   NOTIMPLEMENTED();
147   return kUnknownPower;
150 bool BluetoothClassicDeviceMac::ExpectingPinCode() const {
151   NOTIMPLEMENTED();
152   return false;
155 bool BluetoothClassicDeviceMac::ExpectingPasskey() const {
156   NOTIMPLEMENTED();
157   return false;
160 bool BluetoothClassicDeviceMac::ExpectingConfirmation() const {
161   NOTIMPLEMENTED();
162   return false;
165 void BluetoothClassicDeviceMac::GetConnectionInfo(
166     const ConnectionInfoCallback& callback) {
167   ConnectionInfo connection_info;
168   if (![device_ isConnected]) {
169     callback.Run(connection_info);
170     return;
171   }
173   connection_info.rssi = [device_ rawRSSI];
174   // The API guarantees that +127 is returned in case the RSSI is not readable:
175   // http://goo.gl/bpURYv
176   if (connection_info.rssi == 127)
177     connection_info.rssi = kUnknownPower;
179   connection_info.transmit_power =
180       GetHostTransmitPower(kReadCurrentTransmitPowerLevel);
181   connection_info.max_transmit_power =
182       GetHostTransmitPower(kReadMaximumTransmitPowerLevel);
184   callback.Run(connection_info);
187 void BluetoothClassicDeviceMac::Connect(
188     PairingDelegate* pairing_delegate,
189     const base::Closure& callback,
190     const ConnectErrorCallback& error_callback) {
191   NOTIMPLEMENTED();
194 void BluetoothClassicDeviceMac::SetPinCode(const std::string& pincode) {
195   NOTIMPLEMENTED();
198 void BluetoothClassicDeviceMac::SetPasskey(uint32 passkey) {
199   NOTIMPLEMENTED();
202 void BluetoothClassicDeviceMac::ConfirmPairing() {
203   NOTIMPLEMENTED();
206 void BluetoothClassicDeviceMac::RejectPairing() {
207   NOTIMPLEMENTED();
210 void BluetoothClassicDeviceMac::CancelPairing() {
211   NOTIMPLEMENTED();
214 void BluetoothClassicDeviceMac::Disconnect(
215     const base::Closure& callback,
216     const ErrorCallback& error_callback) {
217   NOTIMPLEMENTED();
220 void BluetoothClassicDeviceMac::Forget(const ErrorCallback& error_callback) {
221   NOTIMPLEMENTED();
224 void BluetoothClassicDeviceMac::ConnectToService(
225     const BluetoothUUID& uuid,
226     const ConnectToServiceCallback& callback,
227     const ConnectToServiceErrorCallback& error_callback) {
228   scoped_refptr<BluetoothSocketMac> socket = BluetoothSocketMac::CreateSocket();
229   socket->Connect(device_.get(), uuid, base::Bind(callback, socket),
230                   error_callback);
233 void BluetoothClassicDeviceMac::ConnectToServiceInsecurely(
234     const BluetoothUUID& uuid,
235     const ConnectToServiceCallback& callback,
236     const ConnectToServiceErrorCallback& error_callback) {
237   error_callback.Run(kApiUnavailable);
240 void BluetoothClassicDeviceMac::CreateGattConnection(
241     const GattConnectionCallback& callback,
242     const ConnectErrorCallback& error_callback) {
243   // TODO(armansito): Implement.
244   error_callback.Run(ERROR_UNSUPPORTED_DEVICE);
247 NSDate* BluetoothClassicDeviceMac::GetLastUpdateTime() const {
248   return [device_ getLastInquiryUpdate];
251 int BluetoothClassicDeviceMac::GetHostTransmitPower(
252     BluetoothHCITransmitPowerLevelType power_level_type) const {
253   IOBluetoothHostController* controller =
254       [IOBluetoothHostController defaultController];
256   // Bail if the undocumented API is unavailable on this machine.
257   SEL selector = @selector(BluetoothHCIReadTransmitPowerLevel:
258                                                        inType:
259                                         outTransmitPowerLevel:);
260   if (![controller respondsToSelector:selector])
261     return kUnknownPower;
263   BluetoothHCITransmitPowerLevel power_level;
264   IOReturn result =
265       [controller BluetoothHCIReadTransmitPowerLevel:[device_ connectionHandle]
266                                               inType:power_level_type
267                                outTransmitPowerLevel:&power_level];
268   if (result != kIOReturnSuccess)
269     return kUnknownPower;
271   return power_level;
274 // static
275 std::string BluetoothClassicDeviceMac::GetDeviceAddress(
276     IOBluetoothDevice* device) {
277   return CanonicalizeAddress(base::SysNSStringToUTF8([device addressString]));
280 }  // namespace device