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 }
53 
Release(hci::Address address)54 void SecurityManagerChannel::Release(hci::Address address) {
55   auto entry = link_map_.find(address);
56   if (entry == link_map_.end()) {
57     LOG_WARN("Unknown address '%s'", address.ToString().c_str());
58     return;
59   }
60   entry->second->Release();
61 }
62 
Disconnect(hci::Address address)63 void SecurityManagerChannel::Disconnect(hci::Address address) {
64   auto entry = link_map_.find(address);
65   if (entry == link_map_.end()) {
66     LOG_WARN("Unknown address '%s'", address.ToString().c_str());
67     return;
68   }
69   entry->second->Disconnect();
70 }
71 
OnCommandComplete(hci::CommandCompleteView packet)72 void SecurityManagerChannel::OnCommandComplete(hci::CommandCompleteView packet) {
73   ASSERT_LOG(packet.IsValid(), "Bad command response");
74 }
75 
SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command)76 void SecurityManagerChannel::SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command) {
77   hci_security_interface_->EnqueueCommand(std::move(command),
78                                           handler_->BindOnceOn(this, &SecurityManagerChannel::OnCommandComplete));
79 }
80 
OnHciEventReceived(hci::EventPacketView packet)81 void SecurityManagerChannel::OnHciEventReceived(hci::EventPacketView packet) {
82   ASSERT_LOG(listener_ != nullptr, "No listener set!");
83   ASSERT(packet.IsValid());
84   listener_->OnHciEventReceived(packet);
85 }
86 
OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link)87 void SecurityManagerChannel::OnLinkConnected(std::unique_ptr<l2cap::classic::LinkSecurityInterface> link) {
88   // Multiple links possible?
89   link->Hold();
90   link->EnsureAuthenticated();
91   link_map_.emplace(link->GetRemoteAddress(), std::move(link));
92 }
93 
OnLinkDisconnected(hci::Address address)94 void SecurityManagerChannel::OnLinkDisconnected(hci::Address address) {
95   auto entry = link_map_.find(address);
96   if (entry == link_map_.end()) {
97     LOG_WARN("Unknown address '%s'", address.ToString().c_str());
98     return;
99   }
100   entry->second.reset();
101   link_map_.erase(entry);
102   ASSERT_LOG(listener_ != nullptr, "Set listener!");
103   listener_->OnConnectionClosed(address);
104 }
105 
106 }  // namespace channel
107 }  // namespace security
108 }  // namespace bluetooth
109