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 |