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