Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / components / pairing / bluetooth_host_pairing_controller.cc
blob74f1a5e21dc0b26ae2224b6f1a9c5f5c23272bb3
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.
5 #include "components/pairing/bluetooth_host_pairing_controller.h"
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"
16 namespace {
17 const int kReceiveSize = 16384;
20 namespace pairing_chromeos {
22 BluetoothHostPairingController::BluetoothHostPairingController()
23 : current_stage_(STAGE_NONE),
24 device_(NULL),
25 proto_decoder_(new ProtoDecoder(this)),
26 ptr_factory_(this) {
29 BluetoothHostPairingController::~BluetoothHostPairingController() {}
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));
38 void BluetoothHostPairingController::SendHostStatus() {
39 pairing_api::HostStatus host_status;
41 host_status.set_api_version(kPairingAPIVersion);
42 if (!enrollment_domain_.empty())
43 host_status.mutable_parameters()->set_domain(enrollment_domain_);
45 // TODO(zork): Get these values from the UI. (http://crbug.com/405744)
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);
51 // TODO(zork): Get a list of other paired controllers.
52 // (http://crbug.com/405757)
54 int size = 0;
55 scoped_refptr<net::IOBuffer> io_buffer(
56 ProtoDecoder::SendHostStatus(host_status, &size));
58 controller_socket_->Send(
59 io_buffer, size,
60 base::Bind(&BluetoothHostPairingController::OnSendComplete,
61 ptr_factory_.GetWeakPtr()),
62 base::Bind(&BluetoothHostPairingController::OnSendError,
63 ptr_factory_.GetWeakPtr()));
66 void BluetoothHostPairingController::AbortWithError(
67 int code,
68 const std::string& message) {
69 if (controller_socket_) {
70 pairing_api::Error error;
72 error.set_api_version(kPairingAPIVersion);
73 error.mutable_parameters()->set_code(PAIRING_ERROR_PAIRING_OR_ENROLLMENT);
74 error.mutable_parameters()->set_description(message);
76 int size = 0;
77 scoped_refptr<net::IOBuffer> io_buffer(
78 ProtoDecoder::SendError(error, &size));
80 controller_socket_->Send(
81 io_buffer, size,
82 base::Bind(&BluetoothHostPairingController::OnSendComplete,
83 ptr_factory_.GetWeakPtr()),
84 base::Bind(&BluetoothHostPairingController::OnSendError,
85 ptr_factory_.GetWeakPtr()));
87 Reset();
90 void BluetoothHostPairingController::Reset() {
91 if (controller_socket_) {
92 controller_socket_->Close();
93 controller_socket_ = NULL;
96 if (service_socket_) {
97 service_socket_->Close();
98 service_socket_ = NULL;
100 ChangeStage(STAGE_NONE);
103 void BluetoothHostPairingController::OnGetAdapter(
104 scoped_refptr<device::BluetoothAdapter> adapter) {
105 DCHECK(thread_checker_.CalledOnValidThread());
106 DCHECK(!adapter_);
107 adapter_ = adapter;
109 // TODO(zork): Make the device name prettier. (http://crbug.com/405774)
110 device_name_ = base::StringPrintf("%s%s", kDeviceNamePrefix,
111 adapter_->GetAddress().c_str());
112 adapter_->SetName(
113 device_name_,
114 base::Bind(&BluetoothHostPairingController::OnSetName,
115 ptr_factory_.GetWeakPtr()),
116 base::Bind(&BluetoothHostPairingController::OnSetError,
117 ptr_factory_.GetWeakPtr()));
120 void BluetoothHostPairingController::OnSetName() {
121 DCHECK(thread_checker_.CalledOnValidThread());
122 if (adapter_->IsPowered()) {
123 OnSetPowered();
124 } else {
125 adapter_->SetPowered(
126 true,
127 base::Bind(&BluetoothHostPairingController::OnSetPowered,
128 ptr_factory_.GetWeakPtr()),
129 base::Bind(&BluetoothHostPairingController::OnSetError,
130 ptr_factory_.GetWeakPtr()));
134 void BluetoothHostPairingController::OnSetPowered() {
135 DCHECK(thread_checker_.CalledOnValidThread());
136 adapter_->AddPairingDelegate(
137 this, device::BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
139 device::BluetoothAdapter::ServiceOptions options;
140 options.name.reset(new std::string(kPairingServiceName));
142 adapter_->CreateRfcommService(
143 device::BluetoothUUID(kPairingServiceUUID), options,
144 base::Bind(&BluetoothHostPairingController::OnCreateService,
145 ptr_factory_.GetWeakPtr()),
146 base::Bind(&BluetoothHostPairingController::OnCreateServiceError,
147 ptr_factory_.GetWeakPtr()));
150 void BluetoothHostPairingController::OnCreateService(
151 scoped_refptr<device::BluetoothSocket> socket) {
152 DCHECK(thread_checker_.CalledOnValidThread());
153 service_socket_ = socket;
155 service_socket_->Accept(
156 base::Bind(&BluetoothHostPairingController::OnAccept,
157 ptr_factory_.GetWeakPtr()),
158 base::Bind(&BluetoothHostPairingController::OnAcceptError,
159 ptr_factory_.GetWeakPtr()));
161 adapter_->SetDiscoverable(
162 true,
163 base::Bind(&BluetoothHostPairingController::OnSetDiscoverable,
164 ptr_factory_.GetWeakPtr(), true),
165 base::Bind(&BluetoothHostPairingController::OnSetError,
166 ptr_factory_.GetWeakPtr()));
169 void BluetoothHostPairingController::OnAccept(
170 const device::BluetoothDevice* device,
171 scoped_refptr<device::BluetoothSocket> socket) {
172 DCHECK(thread_checker_.CalledOnValidThread());
173 adapter_->SetDiscoverable(
174 false,
175 base::Bind(&BluetoothHostPairingController::OnSetDiscoverable,
176 ptr_factory_.GetWeakPtr(), false),
177 base::Bind(&BluetoothHostPairingController::OnSetError,
178 ptr_factory_.GetWeakPtr()));
180 controller_socket_ = socket;
181 service_socket_ = NULL;
183 // TODO: Update Host. (http://crbug.com/405754)
184 SendHostStatus();
186 controller_socket_->Receive(
187 kReceiveSize,
188 base::Bind(&BluetoothHostPairingController::OnReceiveComplete,
189 ptr_factory_.GetWeakPtr()),
190 base::Bind(&BluetoothHostPairingController::OnReceiveError,
191 ptr_factory_.GetWeakPtr()));
193 ChangeStage(STAGE_WAITING_FOR_CREDENTIALS);
196 void BluetoothHostPairingController::OnSetDiscoverable(bool change_stage) {
197 DCHECK(thread_checker_.CalledOnValidThread());
198 if (change_stage) {
199 DCHECK_EQ(current_stage_, STAGE_NONE);
200 ChangeStage(STAGE_WAITING_FOR_CONTROLLER);
204 void BluetoothHostPairingController::OnSendComplete(int bytes_sent) {}
206 void BluetoothHostPairingController::OnReceiveComplete(
207 int bytes, scoped_refptr<net::IOBuffer> io_buffer) {
208 DCHECK(thread_checker_.CalledOnValidThread());
209 proto_decoder_->DecodeIOBuffer(bytes, io_buffer);
211 controller_socket_->Receive(
212 kReceiveSize,
213 base::Bind(&BluetoothHostPairingController::OnReceiveComplete,
214 ptr_factory_.GetWeakPtr()),
215 base::Bind(&BluetoothHostPairingController::OnReceiveError,
216 ptr_factory_.GetWeakPtr()));
219 void BluetoothHostPairingController::OnCreateServiceError(
220 const std::string& message) {
221 LOG(ERROR) << message;
222 // TODO(zork): Add a stage for initialization error. (http://crbug.com/405744)
223 ChangeStage(STAGE_NONE);
226 void BluetoothHostPairingController::OnSetError() {
227 adapter_->RemovePairingDelegate(this);
228 // TODO(zork): Add a stage for initialization error. (http://crbug.com/405744)
229 ChangeStage(STAGE_NONE);
232 void BluetoothHostPairingController::OnAcceptError(
233 const std::string& error_message) {
234 LOG(ERROR) << error_message;
235 Reset();
238 void BluetoothHostPairingController::OnSendError(
239 const std::string& error_message) {
240 LOG(ERROR) << error_message;
243 void BluetoothHostPairingController::OnReceiveError(
244 device::BluetoothSocket::ErrorReason reason,
245 const std::string& error_message) {
246 LOG(ERROR) << reason << ", " << error_message;
247 Reset();
250 void BluetoothHostPairingController::OnHostStatusMessage(
251 const pairing_api::HostStatus& message) {
252 NOTREACHED();
255 void BluetoothHostPairingController::OnConfigureHostMessage(
256 const pairing_api::ConfigureHost& message) {
257 // TODO(zork): Add event to API to handle this case. (http://crbug.com/405744)
260 void BluetoothHostPairingController::OnPairDevicesMessage(
261 const pairing_api::PairDevices& message) {
262 DCHECK(thread_checker_.CalledOnValidThread());
263 if (current_stage_ != STAGE_WAITING_FOR_CREDENTIALS) {
264 AbortWithError(PAIRING_ERROR_PAIRING_OR_ENROLLMENT, kErrorInvalidProtocol);
265 return;
268 ChangeStage(STAGE_ENROLLING);
269 // TODO(zork,achuith): Enroll device, send error on error.
270 // (http://crbug.com/374990)
271 // For now, test domain is sent in the access token.
272 enrollment_domain_ = message.parameters().admin_access_token();
273 ChangeStage(STAGE_PAIRING_DONE);
274 SendHostStatus();
277 void BluetoothHostPairingController::OnCompleteSetupMessage(
278 const pairing_api::CompleteSetup& message) {
279 DCHECK(thread_checker_.CalledOnValidThread());
280 if (current_stage_ != STAGE_PAIRING_DONE) {
281 AbortWithError(PAIRING_ERROR_PAIRING_OR_ENROLLMENT, kErrorInvalidProtocol);
282 return;
285 // TODO(zork): Handle adding another controller. (http://crbug.com/405757)
286 ChangeStage(STAGE_FINISHED);
289 void BluetoothHostPairingController::OnErrorMessage(
290 const pairing_api::Error& message) {
291 NOTREACHED();
294 void BluetoothHostPairingController::AddObserver(Observer* observer) {
295 observers_.AddObserver(observer);
298 void BluetoothHostPairingController::RemoveObserver(Observer* observer) {
299 observers_.RemoveObserver(observer);
302 HostPairingController::Stage BluetoothHostPairingController::GetCurrentStage() {
303 return current_stage_;
306 void BluetoothHostPairingController::StartPairing() {
307 DCHECK_EQ(current_stage_, STAGE_NONE);
308 bool bluetooth_available =
309 device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable();
310 // TODO(zork): Add a stage for initialization error. (http://crbug.com/405744)
311 if (!bluetooth_available)
312 return;
314 device::BluetoothAdapterFactory::GetAdapter(
315 base::Bind(&BluetoothHostPairingController::OnGetAdapter,
316 ptr_factory_.GetWeakPtr()));
319 std::string BluetoothHostPairingController::GetDeviceName() {
320 return device_name_;
323 std::string BluetoothHostPairingController::GetConfirmationCode() {
324 DCHECK_EQ(current_stage_, STAGE_WAITING_FOR_CODE_CONFIRMATION);
325 return confirmation_code_;
328 std::string BluetoothHostPairingController::GetEnrollmentDomain() {
329 return enrollment_domain_;
332 void BluetoothHostPairingController::OnUpdateStatusChanged(
333 UpdateStatus update_status) {
334 // TODO(zork): Handling updating stages (http://crbug.com/405754).
337 void BluetoothHostPairingController::RequestPinCode(
338 device::BluetoothDevice* device) {
339 // Disallow unknown device.
340 device->RejectPairing();
343 void BluetoothHostPairingController::RequestPasskey(
344 device::BluetoothDevice* device) {
345 // Disallow unknown device.
346 device->RejectPairing();
349 void BluetoothHostPairingController::DisplayPinCode(
350 device::BluetoothDevice* device,
351 const std::string& pincode) {
352 // Disallow unknown device.
353 device->RejectPairing();
356 void BluetoothHostPairingController::DisplayPasskey(
357 device::BluetoothDevice* device,
358 uint32 passkey) {
359 // Disallow unknown device.
360 device->RejectPairing();
363 void BluetoothHostPairingController::KeysEntered(
364 device::BluetoothDevice* device,
365 uint32 entered) {
366 // Disallow unknown device.
367 device->RejectPairing();
370 void BluetoothHostPairingController::ConfirmPasskey(
371 device::BluetoothDevice* device,
372 uint32 passkey) {
373 confirmation_code_ = base::StringPrintf("%06d", passkey);
374 device->ConfirmPairing();
375 ChangeStage(STAGE_WAITING_FOR_CODE_CONFIRMATION);
378 void BluetoothHostPairingController::AuthorizePairing(
379 device::BluetoothDevice* device) {
380 // Disallow unknown device.
381 device->RejectPairing();
384 } // namespace pairing_chromeos