11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/pairing/bluetooth_controller_pairing_controller.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/logging.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string_util.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/stringprintf.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/utf_string_conversions.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/pairing/bluetooth_pairing_constants.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/pairing/pairing_api.pb.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/bluetooth/bluetooth_adapter_factory.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/bluetooth/bluetooth_discovery_session.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/io_buffer.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kReceiveSize = 16384;
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace pairing_chromeos {
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBluetoothControllerPairingController::BluetoothControllerPairingController()
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : current_stage_(STAGE_NONE),
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      got_initial_status_(false),
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      proto_decoder_(new ProtoDecoder(this)),
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ptr_factory_(this) {
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBluetoothControllerPairingController::~BluetoothControllerPairingController() {
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Reset();
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccidevice::BluetoothDevice* BluetoothControllerPairingController::GetController() {
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!controller_device_id_.empty());
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothDevice* device = adapter_->GetDevice(controller_device_id_);
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device) {
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(ERROR) << "Lost connection to controller.";
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ChangeStage(STAGE_ESTABLISHING_CONNECTION_ERROR);
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return device;
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::ChangeStage(Stage new_stage) {
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (current_stage_ == new_stage)
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  current_stage_ = new_stage;
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(ControllerPairingController::Observer, observers_,
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    PairingStageChanged(new_stage));
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::Reset() {
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  got_initial_status_ = false;
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller_device_id_.clear();
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  discovery_session_.reset();
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (socket_.get()) {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    socket_->Close();
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    socket_ = NULL;
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (adapter_.get()) {
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    adapter_->RemoveObserver(this);
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    adapter_ = NULL;
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::DeviceFound(
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device) {
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(current_stage_, STAGE_DEVICES_DISCOVERY);
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (StartsWith(device->GetName(), base::ASCIIToUTF16(kDeviceNamePrefix),
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 false)) {
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    discovered_devices_.insert(device->GetAddress());
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FOR_EACH_OBSERVER(ControllerPairingController::Observer, observers_,
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      DiscoveredDevicesListChanged());
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::DeviceLost(
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device) {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(current_stage_, STAGE_DEVICES_DISCOVERY);
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::set<std::string>::iterator ix =
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      discovered_devices_.find(device->GetAddress());
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (ix != discovered_devices_.end()) {
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    discovered_devices_.erase(ix);
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FOR_EACH_OBSERVER(ControllerPairingController::Observer, observers_,
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      DiscoveredDevicesListChanged());
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::SendBuffer(
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<net::IOBuffer> io_buffer, int size) {
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  socket_->Send(
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      io_buffer, size,
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&BluetoothControllerPairingController::OnSendComplete,
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 ptr_factory_.GetWeakPtr()),
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&BluetoothControllerPairingController::OnErrorWithMessage,
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 ptr_factory_.GetWeakPtr()));
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnSetPowered() {
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  adapter_->StartDiscoverySession(
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&BluetoothControllerPairingController::OnStartDiscoverySession,
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 ptr_factory_.GetWeakPtr()),
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&BluetoothControllerPairingController::OnError,
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 ptr_factory_.GetWeakPtr()));
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnGetAdapter(
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<device::BluetoothAdapter> adapter) {
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!adapter_.get());
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  adapter_ = adapter;
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  adapter_->AddObserver(this);
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (adapter_->IsPowered()) {
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OnSetPowered();
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    adapter_->SetPowered(
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        true,
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&BluetoothControllerPairingController::OnSetPowered,
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   ptr_factory_.GetWeakPtr()),
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&BluetoothControllerPairingController::OnError,
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   ptr_factory_.GetWeakPtr()));
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnStartDiscoverySession(
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  discovery_session_ = discovery_session.Pass();
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ChangeStage(STAGE_DEVICES_DISCOVERY);
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothAdapter::DeviceList device_list = adapter_->GetDevices();
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (device::BluetoothAdapter::DeviceList::iterator ix = device_list.begin();
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ix != device_list.end(); ++ix) {
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DeviceFound(*ix);
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnConnect() {
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothDevice* device = GetController();
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (device) {
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device->ConnectToService(
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        device::BluetoothUUID(kPairingServiceUUID),
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&BluetoothControllerPairingController::OnConnectToService,
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   ptr_factory_.GetWeakPtr()),
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&BluetoothControllerPairingController::OnErrorWithMessage,
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   ptr_factory_.GetWeakPtr()));
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnConnectToService(
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<device::BluetoothSocket> socket) {
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  socket_ = socket;
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  socket_->Receive(
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kReceiveSize,
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&BluetoothControllerPairingController::OnReceiveComplete,
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 ptr_factory_.GetWeakPtr()),
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&BluetoothControllerPairingController::OnReceiveError,
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 ptr_factory_.GetWeakPtr()));
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnSendComplete(int bytes_sent) {}
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnReceiveComplete(
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int bytes, scoped_refptr<net::IOBuffer> io_buffer) {
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  proto_decoder_->DecodeIOBuffer(bytes, io_buffer);
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  socket_->Receive(
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kReceiveSize,
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&BluetoothControllerPairingController::OnReceiveComplete,
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 ptr_factory_.GetWeakPtr()),
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&BluetoothControllerPairingController::OnReceiveError,
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 ptr_factory_.GetWeakPtr()));
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnError() {
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  LOG(ERROR) << "Pairing initialization failed";
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ChangeStage(STAGE_INITIALIZATION_ERROR);
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Reset();
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnErrorWithMessage(
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& message) {
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  LOG(ERROR) << message;
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ChangeStage(STAGE_INITIALIZATION_ERROR);
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Reset();
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnConnectError(
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice::ConnectErrorCode error_code) {
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothDevice* device = GetController();
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (device && device->IsPaired()) {
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // The connection attempt is only used to start the pairing between the
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // devices.  If the connection fails, it's not a problem as long as pairing
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // was successful.
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    OnConnect();
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnReceiveError(
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothSocket::ErrorReason reason,
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& error_message) {
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  LOG(ERROR) << reason << ", " << error_message;
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Reset();
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::AddObserver(
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ControllerPairingController::Observer* observer) {
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  observers_.AddObserver(observer);
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::RemoveObserver(
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ControllerPairingController::Observer* observer) {
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  observers_.RemoveObserver(observer);
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciControllerPairingController::Stage
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBluetoothControllerPairingController::GetCurrentStage() {
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return current_stage_;
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::StartPairing() {
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(current_stage_ == STAGE_NONE ||
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         current_stage_ == STAGE_DEVICE_NOT_FOUND ||
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         current_stage_ == STAGE_ESTABLISHING_CONNECTION_ERROR ||
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         current_stage_ == STAGE_HOST_ENROLLMENT_ERROR);
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ChangeStage(STAGE_INITIALIZATION_ERROR);
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothAdapterFactory::GetAdapter(
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&BluetoothControllerPairingController::OnGetAdapter,
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 ptr_factory_.GetWeakPtr()));
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciControllerPairingController::DeviceIdList
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBluetoothControllerPairingController::GetDiscoveredDevices() {
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(current_stage_, STAGE_DEVICES_DISCOVERY);
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return DeviceIdList(discovered_devices_.begin(), discovered_devices_.end());
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::ChooseDeviceForPairing(
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& device_id) {
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(current_stage_, STAGE_DEVICES_DISCOVERY);
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(discovered_devices_.count(device_id));
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  discovery_session_.reset();
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller_device_id_ = device_id;
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothDevice* device = GetController();
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (device) {
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ChangeStage(STAGE_ESTABLISHING_CONNECTION);
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (device->IsPaired()) {
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OnConnect();
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      device->Connect(
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          this,
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          base::Bind(&BluetoothControllerPairingController::OnConnect,
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     ptr_factory_.GetWeakPtr()),
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          base::Bind(&BluetoothControllerPairingController::OnConnectError,
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     ptr_factory_.GetWeakPtr()));
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::RepeatDiscovery() {
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(current_stage_ == STAGE_DEVICE_NOT_FOUND ||
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         current_stage_ == STAGE_ESTABLISHING_CONNECTION_ERROR ||
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         current_stage_ == STAGE_HOST_ENROLLMENT_ERROR);
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Reset();
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StartPairing();
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string BluetoothControllerPairingController::GetConfirmationCode() {
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(current_stage_, STAGE_WAITING_FOR_CODE_CONFIRMATION);
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!confirmation_code_.empty());
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return confirmation_code_;
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::SetConfirmationCodeIsCorrect(
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool correct) {
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(current_stage_, STAGE_WAITING_FOR_CODE_CONFIRMATION);
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothDevice* device = GetController();
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device)
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (correct) {
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device->ConfirmPairing();
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Once pairing is confirmed, the connection will either be successful, or
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // fail.  Either case is acceptable as long as the devices are paired.
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device->RejectPairing();
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    controller_device_id_.clear();
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RepeatDiscovery();
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::SetHostConfiguration(
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool accepted_eula,
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& lang,
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& timezone,
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool send_reports,
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& keyboard_layout) {
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pairing_api::ConfigureHost host_config;
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_config.set_api_version(kPairingAPIVersion);
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_config.mutable_parameters()->set_accepted_eula(accepted_eula);
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_config.mutable_parameters()->set_lang(lang);
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_config.mutable_parameters()->set_timezone(timezone);
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_config.mutable_parameters()->set_send_reports(send_reports);
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_config.mutable_parameters()->set_keyboard_layout(keyboard_layout);
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int size = 0;
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<net::IOBuffer> io_buffer(
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ProtoDecoder::SendConfigureHost(host_config, &size));
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SendBuffer(io_buffer, size);
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnAuthenticationDone(
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& domain,
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& auth_token) {
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(current_stage_, STAGE_WAITING_FOR_CREDENTIALS);
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pairing_api::PairDevices pair_devices;
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pair_devices.set_api_version(kPairingAPIVersion);
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pair_devices.mutable_parameters()->set_admin_access_token(auth_token);
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int size = 0;
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<net::IOBuffer> io_buffer(
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ProtoDecoder::SendPairDevices(pair_devices, &size));
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SendBuffer(io_buffer, size);
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ChangeStage(STAGE_HOST_ENROLLMENT_IN_PROGRESS);
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::StartSession() {
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(current_stage_, STAGE_PAIRING_DONE);
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ChangeStage(STAGE_FINISHED);
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// ProtoDecoder::Observer:
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnHostStatusMessage(
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const pairing_api::HostStatus& message) {
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (got_initial_status_) {
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(zork): Check that the domain matches. (http://crbug.com/405761)
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(zork): Handling updating stages (http://crbug.com/405754).
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pairing_api::CompleteSetup complete_setup;
3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    complete_setup.set_api_version(kPairingAPIVersion);
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(zork): Get AddAnother from UI (http://crbug.com/405757)
3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    complete_setup.mutable_parameters()->set_add_another(false);
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int size = 0;
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<net::IOBuffer> io_buffer(
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ProtoDecoder::SendCompleteSetup(complete_setup, &size));
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SendBuffer(io_buffer, size);
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ChangeStage(STAGE_PAIRING_DONE);
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    got_initial_status_ = true;
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(zork): Check domain. (http://crbug.com/405761)
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ChangeStage(STAGE_WAITING_FOR_CREDENTIALS);
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnConfigureHostMessage(
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const pairing_api::ConfigureHost& message) {
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NOTREACHED();
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnPairDevicesMessage(
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const pairing_api::PairDevices& message) {
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NOTREACHED();
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnCompleteSetupMessage(
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const pairing_api::CompleteSetup& message) {
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NOTREACHED();
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::OnErrorMessage(
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const pairing_api::Error& message) {
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  LOG(ERROR) << message.parameters().code() << ", " <<
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      message.parameters().description();
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ChangeStage(STAGE_HOST_ENROLLMENT_ERROR);
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::DeviceAdded(
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothAdapter* adapter,
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device) {
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(adapter, adapter_.get());
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DeviceFound(device);
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::DeviceRemoved(
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothAdapter* adapter,
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device) {
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(adapter, adapter_.get());
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DeviceLost(device);
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::RequestPinCode(
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device) {
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Disallow unknown device.
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device->RejectPairing();
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::RequestPasskey(
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device) {
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Disallow unknown device.
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device->RejectPairing();
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::DisplayPinCode(
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device,
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& pincode) {
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Disallow unknown device.
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device->RejectPairing();
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::DisplayPasskey(
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device,
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 passkey) {
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Disallow unknown device.
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device->RejectPairing();
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::KeysEntered(
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device,
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 entered) {
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Disallow unknown device.
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device->RejectPairing();
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::ConfirmPasskey(
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device,
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 passkey) {
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  confirmation_code_ = base::StringPrintf("%06d", passkey);
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ChangeStage(STAGE_WAITING_FOR_CODE_CONFIRMATION);
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BluetoothControllerPairingController::AuthorizePairing(
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice* device) {
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Disallow unknown device.
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device->RejectPairing();
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace pairing_chromeos
467