| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/bluetooth/bluetooth_socket_mac.h" | 5 #include "device/bluetooth/bluetooth_socket_mac.h" |
| 6 | 6 |
| 7 #import <IOBluetooth/IOBluetooth.h> | 7 #import <IOBluetooth/IOBluetooth.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <sstream> | 10 #include <sstream> |
| 11 #include <string> | 11 #include <string> |
| 12 | 12 |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/bind.h" | 14 #include "base/bind.h" |
| 15 #include "base/callback.h" | 15 #include "base/callback.h" |
| 16 #include "base/callback_helpers.h" | 16 #include "base/callback_helpers.h" |
| 17 #include "base/mac/scoped_cftyperef.h" | 17 #include "base/mac/scoped_cftyperef.h" |
| 18 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
| 19 #include "base/numerics/safe_conversions.h" | 19 #include "base/numerics/safe_conversions.h" |
| 20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
| 21 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 22 #include "base/strings/sys_string_conversions.h" | 22 #include "base/strings/sys_string_conversions.h" |
| 23 #include "base/threading/thread_restrictions.h" | 23 #include "base/threading/thread_restrictions.h" |
| 24 #include "device/bluetooth/bluetooth_adapter.h" | 24 #include "device/bluetooth/bluetooth_adapter.h" |
| 25 #include "device/bluetooth/bluetooth_adapter_mac.h" |
| 25 #include "device/bluetooth/bluetooth_channel_mac.h" | 26 #include "device/bluetooth/bluetooth_channel_mac.h" |
| 26 #include "device/bluetooth/bluetooth_device.h" | 27 #include "device/bluetooth/bluetooth_device.h" |
| 27 #include "device/bluetooth/bluetooth_device_mac.h" | 28 #include "device/bluetooth/bluetooth_device_mac.h" |
| 28 #include "device/bluetooth/bluetooth_l2cap_channel_mac.h" | 29 #include "device/bluetooth/bluetooth_l2cap_channel_mac.h" |
| 29 #include "device/bluetooth/bluetooth_rfcomm_channel_mac.h" | 30 #include "device/bluetooth/bluetooth_rfcomm_channel_mac.h" |
| 30 #include "net/base/io_buffer.h" | 31 #include "net/base/io_buffer.h" |
| 31 #include "net/base/net_errors.h" | 32 #include "net/base/net_errors.h" |
| 32 | 33 |
| 33 // Replicate specific 10.7 SDK declarations for building with prior SDKs. | 34 // Replicate specific 10.7 SDK declarations for building with prior SDKs. |
| 34 #if !defined(MAC_OS_X_VERSION_10_7) || \ | 35 #if !defined(MAC_OS_X_VERSION_10_7) || \ |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 SDPQueryListener* listener = | 460 SDPQueryListener* listener = |
| 460 [[SDPQueryListener alloc] initWithSocket:this | 461 [[SDPQueryListener alloc] initWithSocket:this |
| 461 device:device | 462 device:device |
| 462 success_callback:success_callback | 463 success_callback:success_callback |
| 463 error_callback:error_callback]; | 464 error_callback:error_callback]; |
| 464 [device performSDPQuery:[listener autorelease] | 465 [device performSDPQuery:[listener autorelease] |
| 465 uuids:@[GetIOBluetoothSDPUUID(uuid_)]]; | 466 uuids:@[GetIOBluetoothSDPUUID(uuid_)]]; |
| 466 } | 467 } |
| 467 | 468 |
| 468 void BluetoothSocketMac::ListenUsingRfcomm( | 469 void BluetoothSocketMac::ListenUsingRfcomm( |
| 469 scoped_refptr<BluetoothAdapter> adapter, | 470 scoped_refptr<BluetoothAdapterMac> adapter, |
| 470 const BluetoothUUID& uuid, | 471 const BluetoothUUID& uuid, |
| 471 int channel_id, | 472 int channel_id, |
| 472 const base::Closure& success_callback, | 473 const base::Closure& success_callback, |
| 473 const ErrorCompletionCallback& error_callback) { | 474 const ErrorCompletionCallback& error_callback) { |
| 474 DCHECK(thread_checker_.CalledOnValidThread()); | 475 DCHECK(thread_checker_.CalledOnValidThread()); |
| 475 | 476 |
| 476 adapter_ = adapter; | 477 adapter_ = adapter; |
| 477 uuid_ = uuid; | 478 uuid_ = uuid; |
| 478 | 479 |
| 479 DVLOG(1) << uuid_.canonical_value() << ": Registering RFCOMM service."; | 480 DVLOG(1) << uuid_.canonical_value() << ": Registering RFCOMM service."; |
| 480 BluetoothRFCOMMChannelID registered_channel_id; | 481 BluetoothRFCOMMChannelID registered_channel_id; |
| 481 service_record_handle_ = | 482 service_record_handle_ = |
| 482 RegisterRfcommService(uuid, channel_id, ®istered_channel_id); | 483 RegisterRfcommService(uuid, channel_id, ®istered_channel_id); |
| 483 if (service_record_handle_ == kInvalidServiceRecordHandle) { | 484 if (service_record_handle_ == kInvalidServiceRecordHandle) { |
| 484 error_callback.Run(kInvalidOrUsedChannel); | 485 error_callback.Run(kInvalidOrUsedChannel); |
| 485 return; | 486 return; |
| 486 } | 487 } |
| 487 | 488 |
| 488 rfcomm_connection_listener_.reset( | 489 rfcomm_connection_listener_.reset( |
| 489 [[BluetoothRfcommConnectionListener alloc] | 490 [[BluetoothRfcommConnectionListener alloc] |
| 490 initWithSocket:this | 491 initWithSocket:this |
| 491 channelID:registered_channel_id]); | 492 channelID:registered_channel_id]); |
| 492 | 493 |
| 493 success_callback.Run(); | 494 success_callback.Run(); |
| 494 } | 495 } |
| 495 | 496 |
| 496 void BluetoothSocketMac::ListenUsingL2cap( | 497 void BluetoothSocketMac::ListenUsingL2cap( |
| 497 scoped_refptr<BluetoothAdapter> adapter, | 498 scoped_refptr<BluetoothAdapterMac> adapter, |
| 498 const BluetoothUUID& uuid, | 499 const BluetoothUUID& uuid, |
| 499 int psm, | 500 int psm, |
| 500 const base::Closure& success_callback, | 501 const base::Closure& success_callback, |
| 501 const ErrorCompletionCallback& error_callback) { | 502 const ErrorCompletionCallback& error_callback) { |
| 502 DCHECK(thread_checker_.CalledOnValidThread()); | 503 DCHECK(thread_checker_.CalledOnValidThread()); |
| 503 | 504 |
| 504 adapter_ = adapter; | 505 adapter_ = adapter; |
| 505 uuid_ = uuid; | 506 uuid_ = uuid; |
| 506 | 507 |
| 507 DVLOG(1) << uuid_.canonical_value() << ": Registering L2CAP service."; | 508 DVLOG(1) << uuid_.canonical_value() << ": Registering L2CAP service."; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 << uuid_.canonical_value() << ": Opening RFCOMM channel: " | 569 << uuid_.canonical_value() << ": Opening RFCOMM channel: " |
| 569 << rfcomm_channel_id; | 570 << rfcomm_channel_id; |
| 570 } else { | 571 } else { |
| 571 DCHECK_NE(l2cap_psm, BluetoothAdapter::kPsmAuto); | 572 DCHECK_NE(l2cap_psm, BluetoothAdapter::kPsmAuto); |
| 572 DVLOG(1) << BluetoothDeviceMac::GetDeviceAddress(device) << " " | 573 DVLOG(1) << BluetoothDeviceMac::GetDeviceAddress(device) << " " |
| 573 << uuid_.canonical_value() << ": Opening L2CAP channel: " | 574 << uuid_.canonical_value() << ": Opening L2CAP channel: " |
| 574 << l2cap_psm; | 575 << l2cap_psm; |
| 575 } | 576 } |
| 576 | 577 |
| 577 // Note: It's important to set the connect callbacks *prior* to opening the | 578 // Note: It's important to set the connect callbacks *prior* to opening the |
| 578 // channel as the delegate is passed in and can synchronously call into | 579 // channel, as opening the channel can synchronously call into |
| 579 // OnChannelOpenComplete(). | 580 // OnChannelOpenComplete(). |
| 580 connect_callbacks_.reset(new ConnectCallbacks()); | 581 connect_callbacks_.reset(new ConnectCallbacks()); |
| 581 connect_callbacks_->success_callback = success_callback; | 582 connect_callbacks_->success_callback = success_callback; |
| 582 connect_callbacks_->error_callback = error_callback; | 583 connect_callbacks_->error_callback = error_callback; |
| 583 | 584 |
| 584 if (rfcomm_channel_id != BluetoothAdapter::kChannelAuto) { | 585 if (rfcomm_channel_id != BluetoothAdapter::kChannelAuto) { |
| 585 channel_ = BluetoothRfcommChannelMac::OpenAsync( | 586 channel_ = BluetoothRfcommChannelMac::OpenAsync( |
| 586 this, device, rfcomm_channel_id, &status); | 587 this, device, rfcomm_channel_id, &status); |
| 587 } else { | 588 } else { |
| 588 DCHECK_NE(l2cap_psm, BluetoothAdapter::kPsmAuto); | 589 DCHECK_NE(l2cap_psm, BluetoothAdapter::kPsmAuto); |
| 589 channel_ = | 590 channel_ = |
| 590 BluetoothL2capChannelMac::OpenAsync(this, device, l2cap_psm, &status); | 591 BluetoothL2capChannelMac::OpenAsync(this, device, l2cap_psm, &status); |
| 591 } | 592 } |
| 592 if (status != kIOReturnSuccess) { | 593 if (status != kIOReturnSuccess) { |
| 594 ReleaseChannel(); |
| 593 std::stringstream error; | 595 std::stringstream error; |
| 594 error << "Failed to connect bluetooth socket (" | 596 error << "Failed to connect bluetooth socket (" |
| 595 << BluetoothDeviceMac::GetDeviceAddress(device) << "): (" << status | 597 << BluetoothDeviceMac::GetDeviceAddress(device) << "): (" << status |
| 596 << ")"; | 598 << ")"; |
| 597 error_callback.Run(error.str()); | 599 error_callback.Run(error.str()); |
| 598 return; | 600 return; |
| 599 } | 601 } |
| 600 | 602 |
| 601 DVLOG(1) << BluetoothDeviceMac::GetDeviceAddress(device) << " " | 603 DVLOG(1) << BluetoothDeviceMac::GetDeviceAddress(device) << " " |
| 602 << uuid_.canonical_value() | 604 << uuid_.canonical_value() |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 AcceptConnectionRequest(); | 849 AcceptConnectionRequest(); |
| 848 } | 850 } |
| 849 | 851 |
| 850 void BluetoothSocketMac::AcceptConnectionRequest() { | 852 void BluetoothSocketMac::AcceptConnectionRequest() { |
| 851 DCHECK(thread_checker_.CalledOnValidThread()); | 853 DCHECK(thread_checker_.CalledOnValidThread()); |
| 852 DVLOG(1) << uuid_.canonical_value() << ": Accepting pending connection."; | 854 DVLOG(1) << uuid_.canonical_value() << ": Accepting pending connection."; |
| 853 | 855 |
| 854 linked_ptr<BluetoothChannelMac> channel = accept_queue_.front(); | 856 linked_ptr<BluetoothChannelMac> channel = accept_queue_.front(); |
| 855 accept_queue_.pop(); | 857 accept_queue_.pop(); |
| 856 | 858 |
| 857 // TODO(isherman): It isn't guaranteed that the adapter knows about the device | 859 adapter_->DeviceConnected(channel->GetDevice()); |
| 858 // at this point. Fix this logic. | |
| 859 BluetoothDevice* device = adapter_->GetDevice(channel->GetDeviceAddress()); | 860 BluetoothDevice* device = adapter_->GetDevice(channel->GetDeviceAddress()); |
| 860 DCHECK(device); | 861 DCHECK(device); |
| 861 | 862 |
| 862 scoped_refptr<BluetoothSocketMac> client_socket = | 863 scoped_refptr<BluetoothSocketMac> client_socket = |
| 863 BluetoothSocketMac::CreateSocket(); | 864 BluetoothSocketMac::CreateSocket(); |
| 864 | 865 |
| 865 client_socket->uuid_ = uuid_; | 866 client_socket->uuid_ = uuid_; |
| 866 client_socket->channel_.reset(channel.release()); | 867 client_socket->channel_.reset(channel.release()); |
| 867 | 868 |
| 868 // Associating the socket can synchronously call into OnChannelOpenComplete(). | 869 // Associating the socket can synchronously call into OnChannelOpenComplete(). |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 rfcomm_connection_listener_.reset(); | 929 rfcomm_connection_listener_.reset(); |
| 929 l2cap_connection_listener_.reset(); | 930 l2cap_connection_listener_.reset(); |
| 930 | 931 |
| 931 // Destroying the listener above prevents the callback delegate from being | 932 // Destroying the listener above prevents the callback delegate from being |
| 932 // called so it is now safe to release all callback state. | 933 // called so it is now safe to release all callback state. |
| 933 accept_request_.reset(); | 934 accept_request_.reset(); |
| 934 empty_queue(accept_queue_); | 935 empty_queue(accept_queue_); |
| 935 } | 936 } |
| 936 | 937 |
| 937 } // namespace device | 938 } // namespace device |
| OLD | NEW |