1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #define LOG_TAG "bt_shim_btif_dm"
17
18 #include "osi/include/log.h"
19
20 #include "main/shim/btif_dm.h"
21 #include "main/shim/entry.h"
22 #include "main/shim/helpers.h"
23 #include "security/security_module.h"
24 #include "security/ui.h"
25
26 using ::bluetooth::shim::GetSecurityModule;
27
28 namespace bluetooth {
29 namespace shim {
30
31 namespace {
32 bool waiting_for_pairing_prompt = false;
33 }
34
35 class ShimUi : public security::UI {
36 public:
~ShimUi()37 ~ShimUi() {}
DisplayPairingPrompt(const bluetooth::hci::AddressWithType & address,std::string name)38 void DisplayPairingPrompt(const bluetooth::hci::AddressWithType& address,
39 std::string name) {
40 waiting_for_pairing_prompt = true;
41 bt_bdname_t legacy_name{0};
42 memcpy(legacy_name.name, name.data(), name.length());
43 callback_(ToRawAddress(address.GetAddress()), legacy_name,
44 ((0x1F) << 8) /* COD_UNCLASSIFIED*/, BT_SSP_VARIANT_CONSENT, 0);
45 }
46
Cancel(const bluetooth::hci::AddressWithType & address)47 void Cancel(const bluetooth::hci::AddressWithType& address) {
48 LOG(WARNING) << " ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ " << __func__;
49 }
50
DisplayConfirmValue(const bluetooth::hci::AddressWithType & address,std::string name,uint32_t numeric_value)51 void DisplayConfirmValue(const bluetooth::hci::AddressWithType& address,
52 std::string name, uint32_t numeric_value) {
53 waiting_for_pairing_prompt = false;
54 bt_bdname_t legacy_name{0};
55 memcpy(legacy_name.name, name.data(), name.length());
56 callback_(ToRawAddress(address.GetAddress()), legacy_name,
57 ((0x1F) << 8) /* COD_UNCLASSIFIED*/,
58 BT_SSP_VARIANT_PASSKEY_CONFIRMATION, numeric_value);
59 }
60
DisplayYesNoDialog(const bluetooth::hci::AddressWithType & address,std::string name)61 void DisplayYesNoDialog(const bluetooth::hci::AddressWithType& address,
62 std::string name) {
63 waiting_for_pairing_prompt = false;
64 bt_bdname_t legacy_name{0};
65 memcpy(legacy_name.name, name.data(), name.length());
66 callback_(ToRawAddress(address.GetAddress()), legacy_name,
67 ((0x1F) << 8) /* COD_UNCLASSIFIED*/, BT_SSP_VARIANT_CONSENT, 0);
68 }
69
DisplayEnterPasskeyDialog(const bluetooth::hci::AddressWithType & address,std::string name)70 void DisplayEnterPasskeyDialog(const bluetooth::hci::AddressWithType& address, std::string name) {
71 waiting_for_pairing_prompt = false;
72 bt_bdname_t legacy_name{0};
73 memcpy(legacy_name.name, name.data(), name.length());
74 callback_(ToRawAddress(address.GetAddress()), legacy_name,
75 ((0x1F) << 8) /* COD_UNCLASSIFIED*/, BT_SSP_VARIANT_PASSKEY_ENTRY,
76 0);
77 }
78
DisplayPasskey(const bluetooth::hci::AddressWithType & address,std::string name,uint32_t passkey)79 void DisplayPasskey(const bluetooth::hci::AddressWithType& address, std::string name, uint32_t passkey) {
80 waiting_for_pairing_prompt = false;
81 bt_bdname_t legacy_name{0};
82 memcpy(legacy_name.name, name.data(), name.length());
83 callback_(ToRawAddress(address.GetAddress()), legacy_name,
84 ((0x1F) << 8) /* COD_UNCLASSIFIED*/,
85 BT_SSP_VARIANT_PASSKEY_NOTIFICATION, passkey);
86 }
87
SetLegacyCallback(std::function<void (RawAddress,bt_bdname_t,uint32_t,bt_ssp_variant_t,uint32_t)> callback)88 void SetLegacyCallback(std::function<void(RawAddress, bt_bdname_t, uint32_t, bt_ssp_variant_t, uint32_t)> callback) {
89 callback_ = callback;
90 }
91
92 private:
93 std::function<void(RawAddress, bt_bdname_t, uint32_t, bt_ssp_variant_t,
94 uint32_t)>
95 callback_;
96 };
97
98 ShimUi ui;
99
100 /**
101 * Sets handler to SecurityModule and provides callback to handler
102 */
BTIF_DM_SetUiCallback(std::function<void (RawAddress,bt_bdname_t,uint32_t,bt_ssp_variant_t,uint32_t)> callback)103 void BTIF_DM_SetUiCallback(std::function<void(RawAddress, bt_bdname_t, uint32_t, bt_ssp_variant_t, uint32_t)> callback) {
104 auto security_manager = bluetooth::shim::GetSecurityModule()->GetSecurityManager();
105 ui.SetLegacyCallback(callback);
106 security_manager->SetUserInterfaceHandler(&ui, bluetooth::shim::GetGdShimHandler());
107 }
108
109 class ShimBondListener : public security::ISecurityManagerListener {
110 public:
SetLegacyCallbacks(std::function<void (RawAddress)> bond_state_bonding_cb,std::function<void (RawAddress)> bond_state_bonded_cb,std::function<void (RawAddress)> bond_state_none_cb)111 void SetLegacyCallbacks(std::function<void(RawAddress)> bond_state_bonding_cb,
112 std::function<void(RawAddress)> bond_state_bonded_cb,
113 std::function<void(RawAddress)> bond_state_none_cb) {
114 bond_state_bonding_cb_ = bond_state_bonding_cb;
115 bond_state_bonded_cb_ = bond_state_bonded_cb;
116 bond_state_none_cb_ = bond_state_none_cb;
117 }
118
OnDeviceBonded(bluetooth::hci::AddressWithType device)119 void OnDeviceBonded(bluetooth::hci::AddressWithType device) override {
120 bond_state_bonded_cb_(ToRawAddress(device.GetAddress()));
121 }
122
OnDeviceUnbonded(bluetooth::hci::AddressWithType device)123 void OnDeviceUnbonded(bluetooth::hci::AddressWithType device) override {
124 bond_state_none_cb_(ToRawAddress(device.GetAddress()));
125 }
126
OnDeviceBondFailed(bluetooth::hci::AddressWithType device)127 void OnDeviceBondFailed(bluetooth::hci::AddressWithType device) override {
128 bond_state_none_cb_(ToRawAddress(device.GetAddress()));
129 }
130
OnEncryptionStateChanged(EncryptionChangeView encryption_change_view)131 void OnEncryptionStateChanged(
132 EncryptionChangeView encryption_change_view) override {}
133
134 std::function<void(RawAddress)> bond_state_bonding_cb_;
135 std::function<void(RawAddress)> bond_state_bonded_cb_;
136 std::function<void(RawAddress)> bond_state_none_cb_;
137 };
138
139 ShimBondListener shim_bond_listener;
140
BTIF_RegisterBondStateChangeListener(std::function<void (RawAddress)> bonding_cb,std::function<void (RawAddress)> bonded_cb,std::function<void (RawAddress)> none_cb)141 void BTIF_RegisterBondStateChangeListener(
142 std::function<void(RawAddress)> bonding_cb,
143 std::function<void(RawAddress)> bonded_cb,
144 std::function<void(RawAddress)> none_cb) {
145 auto security_manager =
146 bluetooth::shim::GetSecurityModule()->GetSecurityManager();
147 shim_bond_listener.SetLegacyCallbacks(bonding_cb, bonded_cb, none_cb);
148 security_manager->RegisterCallbackListener(
149 &shim_bond_listener, bluetooth::shim::GetGdShimHandler());
150 }
151
BTIF_DM_ssp_reply(const RawAddress bd_addr,uint8_t addr_type,bt_ssp_variant_t variant,uint8_t accept)152 void BTIF_DM_ssp_reply(const RawAddress bd_addr, uint8_t addr_type, bt_ssp_variant_t variant, uint8_t accept) {
153 // TODO: GD expects to receive correct address type.
154 // pass addr_type once it's properly set in btif layer
155 hci::AddressWithType address = ToAddressWithType(bd_addr, 0);
156 hci::AddressWithType address2 = ToAddressWithType(bd_addr, 1);
157 auto security_manager = bluetooth::shim::GetSecurityModule()->GetSecurityManager();
158
159 if (variant == BT_SSP_VARIANT_PASSKEY_CONFIRMATION) {
160 if (waiting_for_pairing_prompt) {
161 LOG(INFO) << "interpreting confirmation as pairing accept " << address;
162 security_manager->OnPairingPromptAccepted(address, accept);
163 security_manager->OnPairingPromptAccepted(address2, accept);
164 waiting_for_pairing_prompt = false;
165 } else {
166 LOG(INFO) << "interpreting confirmation as yes/no confirmation "
167 << address;
168 security_manager->OnConfirmYesNo(address, accept);
169 security_manager->OnConfirmYesNo(address2, accept);
170 }
171 } else if (variant == BT_SSP_VARIANT_CONSENT) {
172 LOG(INFO) << "consent ";
173 security_manager->OnConfirmYesNo(address, accept);
174 security_manager->OnConfirmYesNo(address2, accept);
175 } else {
176 //TODO:
177 // void OnPasskeyEntry(const bluetooth::hci::AddressWithType& address, uint32_t passkey) override;
178 LOG(WARNING) << "Variant not implemented yet %02x" << +variant;
179 }
180 }
181
BTIF_DM_pin_reply(const RawAddress bd_addr,uint8_t addr_type,uint8_t accept,uint8_t pin_len,bt_pin_code_t pin_code)182 void BTIF_DM_pin_reply(const RawAddress bd_addr, uint8_t addr_type, uint8_t accept, uint8_t pin_len, bt_pin_code_t pin_code) {
183 // TODO: GD expects to receive correct address type.
184 // pass addr_type once it's properly set in btif layer
185 hci::AddressWithType address = ToAddressWithType(bd_addr, 0);
186 hci::AddressWithType address2 = ToAddressWithType(bd_addr, 1);
187 auto security_manager = bluetooth::shim::GetSecurityModule()->GetSecurityManager();
188
189 if (!accept) {
190 LOG_WARN("This case is not implemented!!");
191 return;
192 }
193
194 uint32_t passkey = 0;
195 int multi[] = {100000, 10000, 1000, 100, 10, 1};
196 for (int i = 0; i < pin_len; i++) {
197 passkey += (multi[i] * (pin_code.pin[i] - '0'));
198 }
199
200 security_manager->OnPasskeyEntry(address, passkey);
201 security_manager->OnPasskeyEntry(address2, passkey);
202 }
203
204 } // namespace shim
205 } // namespace bluetooth
206