Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: device/bluetooth/bluetooth_profile_win.cc

Issue 320463002: Bluetooth: Implement socket API for Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: handle NULL service_record Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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_profile_win.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/sequenced_task_runner.h"
11 #include "base/strings/stringprintf.h"
12 #include "device/bluetooth/bluetooth_adapter_factory.h"
13 #include "device/bluetooth/bluetooth_adapter_win.h"
14 #include "device/bluetooth/bluetooth_device_win.h"
15 #include "device/bluetooth/bluetooth_service_record.h"
16 #include "device/bluetooth/bluetooth_socket_thread.h"
17 #include "device/bluetooth/bluetooth_socket_win.h"
18
19 namespace {
20
21 using device::BluetoothAdapter;
22 using device::BluetoothDevice;
23 using device::BluetoothProfileWin;
24 using device::BluetoothSocket;
25 using device::BluetoothSocketWin;
26
27 const char kNoConnectionCallback[] = "Connection callback not set";
28 const char kProfileNotFound[] = "Profile not found";
29
30 void OnConnectSuccessUIWithAdapter(
31 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
32 const base::Closure& callback,
33 const BluetoothProfileWin::ConnectionCallback& connection_callback,
34 const std::string& device_address,
35 scoped_refptr<BluetoothSocketWin> socket,
36 scoped_refptr<BluetoothAdapter> adapter) {
37 DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
38 const BluetoothDevice* device = adapter->GetDevice(device_address);
39 if (device) {
40 connection_callback.Run(device, socket);
41 callback.Run();
42 }
43 }
44
45 void OnConnectSuccessUI(
46 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
47 const base::Closure& callback,
48 const BluetoothProfileWin::ConnectionCallback& connection_callback,
49 const std::string& device_address,
50 scoped_refptr<BluetoothSocketWin> socket) {
51 DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
52 device::BluetoothAdapterFactory::GetAdapter(
53 base::Bind(&OnConnectSuccessUIWithAdapter,
54 ui_task_runner,
55 callback,
56 connection_callback,
57 device_address,
58 socket));
59 }
60
61 void OnConnectErrorUI(scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
62 const BluetoothProfileWin::ErrorCallback& error_callback,
63 const std::string& error) {
64 DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
65 error_callback.Run(error);
66 }
67
68 std::string IPEndPointToBluetoothAddress(const net::IPEndPoint& end_point) {
69 if (end_point.address().size() != net::kBluetoothAddressSize)
70 return std::string();
71 // The address is copied from BTH_ADDR field of SOCKADDR_BTH, which is a
72 // 64-bit ULONGLONG that stores Bluetooth address in little-endian. Print in
73 // reverse order to preserve the correct ordering.
74 return base::StringPrintf("%02X:%02X:%02X:%02X:%02X:%02X",
75 end_point.address()[5],
76 end_point.address()[4],
77 end_point.address()[3],
78 end_point.address()[2],
79 end_point.address()[1],
80 end_point.address()[0]);
81 }
82
83 } // namespace
84
85 namespace device {
86
87 BluetoothProfileWin::BluetoothProfileWin()
88 : BluetoothProfile(), rfcomm_channel_(0), weak_ptr_factory_(this) {
89 }
90
91 BluetoothProfileWin::~BluetoothProfileWin() {
92 }
93
94 void BluetoothProfileWin::Unregister() {
95 if (profile_socket_)
96 profile_socket_->Close();
97
98 delete this;
99 }
100
101 void BluetoothProfileWin::SetConnectionCallback(
102 const ConnectionCallback& callback) {
103 connection_callback_ = callback;
104 }
105
106 void BluetoothProfileWin::Init(const BluetoothUUID& uuid,
107 const BluetoothProfile::Options& options,
108 const ProfileCallback& callback) {
109 uuid_ = uuid;
110 name_ = options.name;
111 rfcomm_channel_ = options.channel;
112
113 BluetoothAdapterFactory::GetAdapter(
114 base::Bind(&BluetoothProfileWin::OnGetAdapter,
115 weak_ptr_factory_.GetWeakPtr(),
116 callback));
117 }
118
119 void BluetoothProfileWin::Connect(
120 const BluetoothDeviceWin* device,
121 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
122 scoped_refptr<BluetoothSocketThread> socket_thread,
123 net::NetLog* net_log,
124 const net::NetLog::Source& source,
125 const base::Closure& success_callback,
126 const ErrorCallback& error_callback) {
127 DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
128 if (connection_callback_.is_null()) {
129 error_callback.Run(kNoConnectionCallback);
130 return;
131 }
132
133 const BluetoothServiceRecord* record = device->GetServiceRecord(uuid_);
134 if (!record) {
135 error_callback.Run(kProfileNotFound);
136 return;
137 }
138
139 scoped_refptr<BluetoothSocketWin> socket(
140 BluetoothSocketWin::CreateBluetoothSocket(
141 ui_task_runner, socket_thread, net_log, source));
142
143 socket->Connect(*record,
144 base::Bind(&OnConnectSuccessUI,
145 ui_task_runner,
146 success_callback,
147 connection_callback_,
148 device->GetAddress(),
149 socket),
150 error_callback);
151 }
152
153 void BluetoothProfileWin::OnGetAdapter(
154 const ProfileCallback& callback,
155 scoped_refptr<BluetoothAdapter> in_adapter) {
156 DCHECK(!adapter_);
157 DCHECK(!profile_socket_);
158
159 adapter_ = in_adapter;
160 profile_socket_ = BluetoothSocketWin::CreateBluetoothSocket(
161 adapter()->ui_task_runner(),
162 adapter()->socket_thread(),
163 NULL,
164 net::NetLog::Source());
165 profile_socket_->StartService(
166 uuid_,
167 name_,
168 rfcomm_channel_,
169 base::Bind(&BluetoothProfileWin::OnRegisterProfileSuccess,
170 weak_ptr_factory_.GetWeakPtr(),
171 callback),
172 base::Bind(&BluetoothProfileWin::OnRegisterProfileError,
173 weak_ptr_factory_.GetWeakPtr(),
174 callback),
175 base::Bind(&BluetoothProfileWin::OnNewConnection,
176 weak_ptr_factory_.GetWeakPtr()));
177 }
178
179 void BluetoothProfileWin::OnRegisterProfileSuccess(
180 const ProfileCallback& callback) {
181 callback.Run(this);
182 }
183
184 void BluetoothProfileWin::OnRegisterProfileError(
185 const ProfileCallback& callback,
186 const std::string& error_message) {
187 callback.Run(NULL);
188 delete this;
189 }
190
191 void BluetoothProfileWin::OnNewConnection(
192 scoped_refptr<BluetoothSocketWin> connected,
193 const net::IPEndPoint& peer_address) {
194 DCHECK(adapter()->ui_task_runner()->RunsTasksOnCurrentThread());
195 if (connection_callback_.is_null())
196 return;
197
198 std::string device_address = IPEndPointToBluetoothAddress(peer_address);
199 if (device_address.empty()) {
200 LOG(WARNING) << "Failed to accept connection for profile "
201 << "uuid=" << uuid_.value()
202 << ", unexpected peer device address.";
203 return;
204 }
205
206 BluetoothDevice* device = adapter_->GetDevice(device_address);
207 if (!device) {
208 LOG(WARNING) << "Failed to accept connection for profile"
209 << ",uuid=" << uuid_.value()
210 << ", unknown device=" << device_address;
211 return;
212 }
213
214 connection_callback_.Run(device, connected);
215 }
216
217 BluetoothAdapterWin* BluetoothProfileWin::adapter() const {
218 DCHECK(adapter_);
219 return static_cast<BluetoothAdapterWin*>(adapter_.get());
220 }
221
222 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698