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 "hci/address.h"
21 #include "security/smp_packets.h"
22 
23 namespace bluetooth {
24 namespace security {
25 namespace channel {
26 
27 /**
28  * Main Constructor
29  */
SecurityManagerChannel(os::Handler * handler,hci::HciLayer * hci_layer)30 SecurityManagerChannel::SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer)
31     : listener_(nullptr),
32       hci_security_interface_(
33           hci_layer->GetSecurityInterface(handler->BindOn(this, &SecurityManagerChannel::OnHciEventReceived))),
34       handler_(handler),
35       l2cap_security_interface_(nullptr) {}
36 
~SecurityManagerChannel()37 SecurityManagerChannel::~SecurityManagerChannel() {
38   l2cap_security_interface_->Unregister();
39   l2cap_security_interface_ = nullptr;
40 }
41 
Connect(hci::Address address)42 void SecurityManagerChannel::Connect(hci::Address address) {
43   ASSERT_LOG(l2cap_security_interface_ != nullptr, "L2cap Security Interface is null!");
44   auto entry = link_map_.find(address);
45   if (entry != link_map_.end()) {
46     LOG_WARN("Already connected to '%s'", address.ToString().c_str());
47     entry->second->Hold();
48     entry->second->EnsureAuthenticated();
49     return;
50   }
51   l2cap_security_interface_->InitiateConnectionForSecurity(address);
52   outgoing_pairing_remote_devices_.insert(address);
53 }
54 
Release(hci::Address address)55 void SecurityManagerChannel::Release(hci::Address address) {
56   auto entry = link_map_.find(address);
57   if (entry == link_map_.end()) {
58     LOG_WARN("Unknown address '%s'", address.ToString().c_str());
59     return;
60   }
61   entry->second->Release();
62 }
63 
Disconnect(hci::Address address)64 void SecurityManagerChannel::Disconnect(hci::Address address) {
65   outgoing_pairing_remote_devices_.erase(address);
66   auto entry = link_map_.find(address);
67   if (entry == link_map_.end()) {
68     LOG_WARN("Unknown address '%s'", address.ToString().c_str());
69     return;
70   }
71   entry->second->Disconnect();
72 }
73 
OnCommandComplete(hci::CommandCompleteView packet)74 void SecurityManagerChannel::OnCommandComplete(hci::CommandCompleteView packet) {
75   ASSERT_LOG(packet.IsValid(), "Bad command response");
76 }
77 
SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command)78 void SecurityManagerChannel::SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command) {
79   hci_security_interface_->EnqueueCommand(std::move(command),
80                                           handler_->BindOnceOn(this, &SecurityManagerChannel::OnCommandComplete));
81 }
82 
SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command,SecurityCommandStatusCallback callback)83 void SecurityManagerChannel::SendCommand(
84     std::unique_ptr<hci::SecurityCommandBuilder> command, SecurityCommandStatusCallback callback) {
85   hci_security_interface_->EnqueueCommand(std::move(command), std::forward<SecurityCommandStatusCallback>(callback));
86 }
87 
OnHciEventReceived(hci::EventView packet)88 void SecurityManagerChannel::OnHciEventReceived(hci::EventView packet) {
89   ASSERT_LOG(listener_ != nullptr, "No listener set!");
90   ASSERT(packet.IsValid());
91   listener_->OnHciEventReceived(packet);
92 }
93 
OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link)94 void SecurityManagerChannel::OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) {
95   // Multiple links possible?
96   auto remote = link->GetRemoteAddress();
97   if (outgoing_pairing_remote_devices_.count(remote) == 1) {
98     link->Hold();
99     link->EnsureAuthenticated();
100     outgoing_pairing_remote_devices_.erase(remote);
101   }
102   link_map_.emplace(remote, std::move(link));
103 }
104 
OnLinkDisconnected(hci::Address address)105 void SecurityManagerChannel::OnLinkDisconnected(hci::Address address) {
106   auto entry = link_map_.find(address);
107   if (entry == link_map_.end()) {
108     LOG_WARN("Unknown address '%s'", address.ToString().c_str());
109     return;
110   }
111   entry->second.reset();
112   link_map_.erase(entry);
113   ASSERT_LOG(listener_ != nullptr, "Set listener!");
114   listener_->OnConnectionClosed(address);
115 }
116 
OnAuthenticationComplete(hci::ErrorCode hci_status,hci::Address remote)117 void SecurityManagerChannel::OnAuthenticationComplete(hci::ErrorCode hci_status, hci::Address remote) {
118   ASSERT_LOG(l2cap_security_interface_ != nullptr, "L2cap Security Interface is null!");
119   auto entry = link_map_.find(remote);
120   if (entry != link_map_.end()) {
121     entry->second->EnsureEncrypted();
122     return;
123   }
124 }
125 
OnEncryptionChange(hci::Address remote,bool encrypted)126 void SecurityManagerChannel::OnEncryptionChange(hci::Address remote, bool encrypted) {
127 }
128 
129 }  // namespace channel
130 }  // namespace security
131 }  // namespace bluetooth
132