1 /*
2  *
3  *  Copyright 2019 The Android Open Source Project
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  */
18 #include "security/channel/security_manager_channel.h"
19 
20 #include <bluetooth/log.h>
21 
22 #include "hci/address.h"
23 
24 namespace bluetooth {
25 namespace security {
26 namespace channel {
27 
28 /**
29  * Main Constructor
30  */
SecurityManagerChannel(os::Handler * handler,hci::HciLayer * hci_layer)31 SecurityManagerChannel::SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer)
32     : listener_(nullptr),
33       hci_security_interface_(
34           hci_layer->GetSecurityInterface(handler->BindOn(this, &SecurityManagerChannel::OnHciEventReceived))),
35       handler_(handler),
36       l2cap_security_interface_(nullptr) {}
37 
~SecurityManagerChannel()38 SecurityManagerChannel::~SecurityManagerChannel() {
39   l2cap_security_interface_->Unregister();
40   l2cap_security_interface_ = nullptr;
41 }
42 
Connect(hci::Address address)43 void SecurityManagerChannel::Connect(hci::Address address) {
44   log::assert_that(l2cap_security_interface_ != nullptr, "L2cap Security Interface is null!");
45   auto entry = link_map_.find(address);
46   if (entry != link_map_.end()) {
47     log::warn("Already connected to '{}'", address);
48     entry->second->Hold();
49     entry->second->EnsureAuthenticated();
50     return;
51   }
52   l2cap_security_interface_->InitiateConnectionForSecurity(address);
53   outgoing_pairing_remote_devices_.insert(address);
54 }
55 
Release(hci::Address address)56 void SecurityManagerChannel::Release(hci::Address address) {
57   auto entry = link_map_.find(address);
58   if (entry == link_map_.end()) {
59     log::warn("Unknown address '{}'", address);
60     return;
61   }
62   entry->second->Release();
63 }
64 
Disconnect(hci::Address address)65 void SecurityManagerChannel::Disconnect(hci::Address address) {
66   outgoing_pairing_remote_devices_.erase(address);
67   auto entry = link_map_.find(address);
68   if (entry == link_map_.end()) {
69     log::warn("Unknown address '{}'", address);
70     return;
71   }
72   entry->second->Disconnect();
73 }
74 
OnCommandComplete(hci::CommandCompleteView packet)75 void SecurityManagerChannel::OnCommandComplete(hci::CommandCompleteView packet) {
76   log::assert_that(packet.IsValid(), "Bad command response");
77 }
78 
SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command)79 void SecurityManagerChannel::SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command) {
80   hci_security_interface_->EnqueueCommand(std::move(command),
81                                           handler_->BindOnceOn(this, &SecurityManagerChannel::OnCommandComplete));
82 }
83 
SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command,SecurityCommandStatusCallback callback)84 void SecurityManagerChannel::SendCommand(
85     std::unique_ptr<hci::SecurityCommandBuilder> command, SecurityCommandStatusCallback callback) {
86   hci_security_interface_->EnqueueCommand(std::move(command), std::forward<SecurityCommandStatusCallback>(callback));
87 }
88 
OnHciEventReceived(hci::EventView packet)89 void SecurityManagerChannel::OnHciEventReceived(hci::EventView packet) {
90   log::assert_that(listener_ != nullptr, "No listener set!");
91   log::assert_that(packet.IsValid(), "assert failed: packet.IsValid()");
92   listener_->OnHciEventReceived(packet);
93 }
94 
OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link)95 void SecurityManagerChannel::OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) {
96   // Multiple links possible?
97   auto remote = link->GetRemoteAddress();
98   if (outgoing_pairing_remote_devices_.count(remote) == 1) {
99     link->Hold();
100     link->EnsureAuthenticated();
101     outgoing_pairing_remote_devices_.erase(remote);
102   }
103   link_map_.emplace(remote, std::move(link));
104 }
105 
OnLinkDisconnected(hci::Address address)106 void SecurityManagerChannel::OnLinkDisconnected(hci::Address address) {
107   auto entry = link_map_.find(address);
108   if (entry == link_map_.end()) {
109     log::warn("Unknown address '{}'", address);
110     return;
111   }
112   entry->second.reset();
113   link_map_.erase(entry);
114   log::assert_that(listener_ != nullptr, "Set listener!");
115   listener_->OnConnectionClosed(address);
116 }
117 
OnAuthenticationComplete(hci::ErrorCode,hci::Address remote)118 void SecurityManagerChannel::OnAuthenticationComplete(
119     hci::ErrorCode /* hci_status */, hci::Address remote) {
120   log::assert_that(l2cap_security_interface_ != nullptr, "L2cap Security Interface is null!");
121   auto entry = link_map_.find(remote);
122   if (entry != link_map_.end()) {
123     entry->second->EnsureEncrypted();
124     return;
125   }
126 }
127 
OnEncryptionChange(hci::Address,bool)128 void SecurityManagerChannel::OnEncryptionChange(hci::Address /* remote */, bool /* encrypted */) {}
129 
130 }  // namespace channel
131 }  // namespace security
132 }  // namespace bluetooth
133