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