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

Side by Side Diff: components/pairing/bluetooth_host_pairing_controller.cc

Issue 469613002: Add bluetooth host and controller delegates for pairing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 2014 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 "components/pairing/bluetooth_host_pairing_controller.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h"
10 #include "components/pairing/bluetooth_pairing_constants.h"
11 #include "components/pairing/pairing_api.pb.h"
12 #include "components/pairing/proto_decoder.h"
13 #include "device/bluetooth/bluetooth_adapter_factory.h"
14 #include "net/base/io_buffer.h"
15
16 namespace {
17 const int kReceiveSize = 16384;
18 }
19
20 namespace pairing_chromeos {
21
22 BluetoothHostPairingController::BluetoothHostPairingController()
23 : ptr_factory_(this),
24 current_stage_(STAGE_NONE),
25 device_(NULL),
26 proto_decoder_(new ProtoDecoder(this)) {
27 }
28
29 BluetoothHostPairingController::~BluetoothHostPairingController() {}
30
31 void BluetoothHostPairingController::ChangeStage(Stage new_stage) {
32 if (current_stage_ == new_stage)
33 return;
34 current_stage_ = new_stage;
35 FOR_EACH_OBSERVER(Observer, observers_, PairingStageChanged(new_stage));
36 }
37
38 void BluetoothHostPairingController::SendHostStatus() {
39 pairing_api::HostStatus host_status;
40
41 host_status.set_api_version(kPairingAPIVersion);
42 if (!enrollment_domain_.empty())
43 host_status.mutable_parameters()->set_domain(enrollment_domain_);
44
45 // TODO: Get these values from the UI.
achuithb 2014/08/20 21:52:33 TODO(zork) + bug-id
Zachary Kuznia 2014/08/21 00:42:07 Done.
46 host_status.mutable_parameters()->set_connectivity(
47 pairing_api::HostStatusParameters::CONNECTIVITY_CONNECTED);
48 host_status.mutable_parameters()->set_update_status(
49 pairing_api::HostStatusParameters::UPDATE_STATUS_UPDATED);
50
51 // TODO: Get a list of other paired controllers.
achuithb 2014/08/20 21:52:34 TODO(zork) + bug-id
Zachary Kuznia 2014/08/21 00:42:07 Done.
52
53 int size = 0;
54 scoped_refptr<net::IOBuffer> io_buffer(
55 ProtoDecoder::SendHostStatus(host_status, &size));
56
57 controller_socket_->Send(
58 io_buffer, size,
59 base::Bind(&BluetoothHostPairingController::OnSendComplete,
60 ptr_factory_.GetWeakPtr()),
61 base::Bind(&BluetoothHostPairingController::OnSendError,
62 ptr_factory_.GetWeakPtr()));
63 }
64
65 void BluetoothHostPairingController::AbortWithError(
66 int code,
67 const std::string& message) {
68 if (controller_socket_) {
69 pairing_api::Error error;
70
71 error.set_api_version(kPairingAPIVersion);
72 error.mutable_parameters()->set_code(PAIRING_ERROR_PAIRING_OR_ENROLLMENT);
73 error.mutable_parameters()->set_description(message);
74
75 int size = 0;
76 scoped_refptr<net::IOBuffer> io_buffer(
77 ProtoDecoder::SendError(error, &size));
78
79 controller_socket_->Send(
80 io_buffer, size,
81 base::Bind(&BluetoothHostPairingController::OnSendComplete,
82 ptr_factory_.GetWeakPtr()),
83 base::Bind(&BluetoothHostPairingController::OnSendError,
84 ptr_factory_.GetWeakPtr()));
85 }
86 Reset();
87 }
88
89 void BluetoothHostPairingController::Reset() {
90 if (controller_socket_) {
91 controller_socket_->Close();
92 controller_socket_ = NULL;
93 }
94
95 if (service_socket_) {
96 service_socket_->Close();
97 service_socket_ = NULL;
98 }
99 ChangeStage(STAGE_NONE);
100 }
101
102 void BluetoothHostPairingController::OnGetAdapter(
103 scoped_refptr<device::BluetoothAdapter> adapter) {
104 CHECK(!adapter_);
achuithb 2014/08/20 21:52:34 Why CHECK?
Zachary Kuznia 2014/08/21 00:42:08 Done.
105 adapter_ = adapter;
106
107 // TODO(zork): Make the device name prettier.
achuithb 2014/08/20 21:52:33 bug-id
Zachary Kuznia 2014/08/21 00:42:07 Done.
108 device_name_ = base::StringPrintf("%s%s", kDeviceNamePrefix,
109 adapter_->GetAddress().c_str());
110 adapter_->SetName(
111 device_name_,
112 base::Bind(&BluetoothHostPairingController::OnSetName,
113 ptr_factory_.GetWeakPtr()),
114 base::Bind(&BluetoothHostPairingController::OnSetError,
115 ptr_factory_.GetWeakPtr()));
116 }
117
118 void BluetoothHostPairingController::OnSetName() {
119 if (adapter_->IsPowered()) {
120 OnSetPowered();
121 } else {
122 adapter_->SetPowered(
123 true,
124 base::Bind(&BluetoothHostPairingController::OnSetPowered,
125 ptr_factory_.GetWeakPtr()),
126 base::Bind(&BluetoothHostPairingController::OnSetError,
127 ptr_factory_.GetWeakPtr()));
128 }
129 }
130
131 void BluetoothHostPairingController::OnSetPowered() {
132 adapter_->AddPairingDelegate(
133 this, device::BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
134
135 device::BluetoothAdapter::ServiceOptions options;
136 options.name.reset(new std::string(kPairingServiceName));
137
138 adapter_->CreateRfcommService(
139 device::BluetoothUUID(kPairingServiceUUID), options,
140 base::Bind(&BluetoothHostPairingController::OnCreateService,
141 ptr_factory_.GetWeakPtr()),
142 base::Bind(&BluetoothHostPairingController::OnCreateServiceError,
143 ptr_factory_.GetWeakPtr()));
144 }
145
146 void BluetoothHostPairingController::OnCreateService(
147 scoped_refptr<device::BluetoothSocket> socket) {
148 service_socket_ = socket;
149
150 service_socket_->Accept(
151 base::Bind(&BluetoothHostPairingController::OnAccept,
152 ptr_factory_.GetWeakPtr()),
153 base::Bind(&BluetoothHostPairingController::OnAcceptError,
154 ptr_factory_.GetWeakPtr()));
155
156 adapter_->SetDiscoverable(
157 true,
158 base::Bind(&BluetoothHostPairingController::OnSetDiscoverable,
159 ptr_factory_.GetWeakPtr(), true),
160 base::Bind(&BluetoothHostPairingController::OnSetError,
161 ptr_factory_.GetWeakPtr()));
162 }
163
164 void BluetoothHostPairingController::OnAccept(
165 const device::BluetoothDevice* device,
166 scoped_refptr<device::BluetoothSocket> socket) {
167 adapter_->SetDiscoverable(
168 false,
169 base::Bind(&BluetoothHostPairingController::OnSetDiscoverable,
170 ptr_factory_.GetWeakPtr(), false),
171 base::Bind(&BluetoothHostPairingController::OnSetError,
172 ptr_factory_.GetWeakPtr()));
173
174 controller_socket_ = socket;
175 service_socket_ = NULL;
176
177 // TODO: Update Host.
achuithb 2014/08/20 21:52:34 TODO(zork) + bug-id
Zachary Kuznia 2014/08/21 00:42:07 Done.
178 SendHostStatus();
179
180 controller_socket_->Receive(
181 kReceiveSize,
182 base::Bind(&BluetoothHostPairingController::OnReceiveComplete,
183 ptr_factory_.GetWeakPtr()),
184 base::Bind(&BluetoothHostPairingController::OnReceiveError,
185 ptr_factory_.GetWeakPtr()));
186
187 ChangeStage(STAGE_WAITING_FOR_CREDENTIALS);
188 }
189
190 void BluetoothHostPairingController::OnSetDiscoverable(bool change_stage) {
191 if (change_stage) {
192 DCHECK_EQ(current_stage_, STAGE_NONE);
193 ChangeStage(STAGE_WAITING_FOR_CONTROLLER);
194 }
195 }
196
197 void BluetoothHostPairingController::OnSendComplete(int bytes_sent) {}
198
199 void BluetoothHostPairingController::OnReceiveComplete(
200 int bytes, scoped_refptr<net::IOBuffer> io_buffer) {
201 proto_decoder_->DecodeIOBuffer(bytes, io_buffer);
202
203 controller_socket_->Receive(
204 kReceiveSize,
205 base::Bind(&BluetoothHostPairingController::OnReceiveComplete,
206 ptr_factory_.GetWeakPtr()),
207 base::Bind(&BluetoothHostPairingController::OnReceiveError,
208 ptr_factory_.GetWeakPtr()));
209 }
210
211 void BluetoothHostPairingController::OnCreateServiceError(
212 const std::string& message) {
213 LOG(ERROR) << message;
214 // TODO(zork): Add a stage for bluetooth error.
achuithb 2014/08/20 21:52:34 bug-id
Zachary Kuznia 2014/08/21 00:42:08 Done.
215 ChangeStage(STAGE_NONE);
216 }
217
218 void BluetoothHostPairingController::OnSetError() {
219 adapter_->RemovePairingDelegate(this);
220 // TODO(zork): Add a stage for bluetooth error.
achuithb 2014/08/20 21:52:33 bug-id
Zachary Kuznia 2014/08/21 00:42:07 Done.
221 ChangeStage(STAGE_NONE);
222 }
223
224 void BluetoothHostPairingController::OnAcceptError(
225 const std::string& error_message) {
226 LOG(ERROR) << error_message;
227 Reset();
228 }
229
230 void BluetoothHostPairingController::OnSendError(
231 const std::string& error_message) {
232 LOG(ERROR) << error_message;
233 }
234
235 void BluetoothHostPairingController::OnReceiveError(
236 device::BluetoothSocket::ErrorReason reason,
237 const std::string& error_message) {
238 LOG(ERROR) << reason << ", " << error_message;
239 Reset();
240 }
241
242 void BluetoothHostPairingController::OnHostStatusMessage(
243 const pairing_api::HostStatus& message) {
244 NOTREACHED();
245 }
246
247 void BluetoothHostPairingController::OnConfigureHostMessage(
248 const pairing_api::ConfigureHost& message) {
249 // TODO(zork): Add event to API to handle this case.
achuithb 2014/08/20 21:52:33 bug-id
Zachary Kuznia 2014/08/21 00:42:07 Done.
250 }
251
252 void BluetoothHostPairingController::OnPairDevicesMessage(
253 const pairing_api::PairDevices& message) {
254 if (current_stage_ != STAGE_WAITING_FOR_CREDENTIALS) {
255 AbortWithError(PAIRING_ERROR_PAIRING_OR_ENROLLMENT, kErrorInvalidProtocol);
256 return;
257 }
258
259 if (enrollment_domain_.empty()) {
260 ChangeStage(STAGE_ENROLLING);
261 // TODO: Enroll device, send error on error
achuithb 2014/08/20 21:52:33 TODO(zork/achuith) + bug-id
Zachary Kuznia 2014/08/21 00:42:08 Done.
262 // For now, test domain is sent in the access token.
263 enrollment_domain_ = message.parameters().admin_access_token();
264 ChangeStage(STAGE_PAIRING_DONE);
265 SendHostStatus();
266 } else {
267 // TODO: Check that domain matches. If not, send error and abort.
achuithb 2014/08/20 21:52:33 TODO(zork/achuith) + bug-id Did we decide to do t
Zachary Kuznia 2014/08/21 00:42:08 Done.
268 NOTREACHED();
269 }
270 }
271
272 void BluetoothHostPairingController::OnCompleteSetupMessage(
273 const pairing_api::CompleteSetup& message) {
274 if (current_stage_ != STAGE_PAIRING_DONE) {
275 AbortWithError(PAIRING_ERROR_PAIRING_OR_ENROLLMENT, kErrorInvalidProtocol);
276 return;
277 }
278
279 // TODO(zork): Handle adding another controller.
achuithb 2014/08/20 21:52:34 bug-id
Zachary Kuznia 2014/08/21 00:42:08 Done.
280 ChangeStage(STAGE_FINISHED);
281 }
282
283 void BluetoothHostPairingController::OnErrorMessage(
284 const pairing_api::Error& message) {
285 NOTREACHED();
286 }
287
288 // HostPairingFlow:
achuithb 2014/08/20 21:52:33 REmove comment
Zachary Kuznia 2014/08/21 00:42:07 Done.
289 void BluetoothHostPairingController::AddObserver(Observer* observer) {
290 observers_.AddObserver(observer);
291 }
292
293 void BluetoothHostPairingController::RemoveObserver(Observer* observer) {
294 observers_.RemoveObserver(observer);
295 }
296
297 HostPairingController::Stage BluetoothHostPairingController::GetCurrentStage() {
achuithb 2014/08/20 21:52:34 This should be current_stage() and defined in the
Zachary Kuznia 2014/08/21 00:42:07 Acknowledged.
298 return current_stage_;
299 }
300
301 void BluetoothHostPairingController::StartPairing() {
302 CHECK(current_stage_ == STAGE_NONE);
achuithb 2014/08/20 21:52:34 Why CHECK?
Zachary Kuznia 2014/08/21 00:42:08 Acknowledged.
303 bool bluetooth_available =
304 device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable();
305 // TODO(zork): Add a stage for no bluetooth.
achuithb 2014/08/20 21:52:33 bug-id
Zachary Kuznia 2014/08/21 00:42:07 Done.
306 if (!bluetooth_available)
307 return;
308
309 device::BluetoothAdapterFactory::GetAdapter(
310 base::Bind(&BluetoothHostPairingController::OnGetAdapter,
311 ptr_factory_.GetWeakPtr()));
312 }
313
314 std::string BluetoothHostPairingController::GetDeviceName() {
achuithb 2014/08/20 21:52:33 const std::string& device_name() const
Zachary Kuznia 2014/08/21 00:42:07 Acknowledged.
315 return device_name_;
316 }
317
318 std::string BluetoothHostPairingController::GetConfirmationCode() {
achuithb 2014/08/20 21:52:34 const std::string& GetConfirmationCode() const
Zachary Kuznia 2014/08/21 00:42:08 Acknowledged.
319 CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION);
achuithb 2014/08/20 21:52:34 Why CHECK?
Zachary Kuznia 2014/08/21 00:42:07 Done.
320 return confirmation_code_;
321 }
322
323 std::string BluetoothHostPairingController::GetEnrollmentDomain() {
achuithb 2014/08/20 21:52:34 const std::string& enrollment_domain() const
Zachary Kuznia 2014/08/21 00:42:07 This is a virtual function, as we discussed.
324 return enrollment_domain_;
325 }
326
327 // device::BluetoothDevice::PairingDelegate:
328 void BluetoothHostPairingController::RequestPinCode(
329 device::BluetoothDevice* device) {
330 // Disallow unknown device.
331 device->RejectPairing();
332 }
333
334 void BluetoothHostPairingController::RequestPasskey(
335 device::BluetoothDevice* device) {
336 // Disallow unknown device.
337 device->RejectPairing();
338 }
339
340 void BluetoothHostPairingController::DisplayPinCode(
341 device::BluetoothDevice* device,
342 const std::string& pincode) {
343 // Disallow unknown device.
344 device->RejectPairing();
345 }
346
347 void BluetoothHostPairingController::DisplayPasskey(
348 device::BluetoothDevice* device,
349 uint32 passkey) {
350 // Disallow unknown device.
351 device->RejectPairing();
352 }
353
354 void BluetoothHostPairingController::KeysEntered(
355 device::BluetoothDevice* device,
356 uint32 entered) {
357 // Disallow unknown device.
358 device->RejectPairing();
359 }
360
361 void BluetoothHostPairingController::ConfirmPasskey(
362 device::BluetoothDevice* device,
363 uint32 passkey) {
364 confirmation_code_ = base::StringPrintf("%06d", passkey);
365 device->ConfirmPairing();
366 ChangeStage(STAGE_WAITING_FOR_CODE_CONFIRMATION);
367 }
368
369 void BluetoothHostPairingController::AuthorizePairing(
370 device::BluetoothDevice* device) {
371 // Disallow unknown device.
372 device->RejectPairing();
373 }
374
375 } // namespace pairing_chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698