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