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
17 #include "main/shim/link_policy.h"
18
19 #include <base/bind.h>
20 #include <base/location.h>
21 #include <base/strings/stringprintf.h>
22
23 #include <cstdint>
24 #include <memory>
25
26 #include "device/include/interop.h"
27 #include "hci/controller.h"
28 #include "main/shim/controller.h"
29 #include "main/shim/dumpsys.h"
30 #include "main/shim/stack.h"
31 #include "osi/include/log.h"
32 #include "osi/include/osi.h" // UNUSED_ATTR
33 #include "stack/btm/btm_int_types.h"
34 #include "stack/include/btm_api.h"
35 #include "stack/include/btm_api_types.h"
36 #include "stack/include/btm_ble_api_types.h"
37 #include "stack/include/hci_error_code.h"
38 #include "types/raw_address.h"
39
40 bt_status_t do_in_main_thread(const base::Location& from_here,
41 base::OnceClosure task);
42
43 void btm_cont_rswitch_from_handle(uint16_t hci_handle);
44 void btm_pm_proc_mode_change(tHCI_STATUS hci_status, uint16_t hci_handle,
45 tHCI_MODE mode, uint16_t interval);
46 void btm_sco_chk_pend_unpark(tHCI_STATUS hci_status, uint16_t hci_handle);
47 void l2c_OnHciModeChangeSendPendingPackets(RawAddress remote);
48 void process_ssr_event(tHCI_STATUS status, uint16_t handle,
49 UNUSED_ATTR uint16_t max_tx_lat, uint16_t max_rx_lat);
50 tACL_CONN* acl_get_connection_from_handle(uint16_t handle);
51
52 extern tBTM_CB btm_cb;
53
54 namespace {
55
set_active_mode(tACL_CONN & p_acl)56 tBTM_STATUS set_active_mode(tACL_CONN& p_acl) {
57 bluetooth::shim::Stack::GetInstance()->LinkPolicy()->ExitSniffMode(
58 p_acl.hci_handle);
59 return BTM_SUCCESS;
60 }
61
set_hold_mode(tACL_CONN & p_acl,uint16_t max,uint16_t min)62 tBTM_STATUS set_hold_mode(tACL_CONN& p_acl, uint16_t max, uint16_t min) {
63 bluetooth::shim::Stack::GetInstance()->LinkPolicy()->HoldMode(
64 p_acl.hci_handle, max, min);
65 return BTM_SUCCESS;
66 }
67
set_sniff_mode(tACL_CONN & p_acl,uint16_t max_interval,uint16_t min_interval,uint16_t attempt,uint16_t timeout)68 tBTM_STATUS set_sniff_mode(tACL_CONN& p_acl, uint16_t max_interval,
69 uint16_t min_interval, uint16_t attempt,
70 uint16_t timeout) {
71 bluetooth::shim::Stack::GetInstance()->LinkPolicy()->SniffMode(
72 p_acl.hci_handle, max_interval, min_interval, attempt, timeout);
73 return BTM_SUCCESS;
74 }
75
controller_supports_link_policy_mode(const tBTM_PM_MODE & mode,bool interop_check)76 bool controller_supports_link_policy_mode(const tBTM_PM_MODE& mode,
77 bool interop_check) {
78 switch (mode) {
79 case BTM_PM_MD_ACTIVE: // Active mode is always supported
80 break;
81 case BTM_PM_MD_PARK: // Park mode no longer supported
82 return false;
83 case BTM_PM_MD_SNIFF:
84 if (!controller_get_interface()->supports_sniff_mode() || interop_check)
85 return false;
86 break;
87 case BTM_PM_MD_HOLD:
88 if (!controller_get_interface()->supports_hold_mode() || interop_check)
89 return false;
90 break;
91 default:
92 LOG_ERROR("Unknown mode:%u", mode);
93 return false;
94 }
95 return true;
96 }
97
98 } // namespace
99
RegisterLinkPolicyClient(tBTM_PM_STATUS_CBACK * p_cb)100 bool bluetooth::shim::RegisterLinkPolicyClient(tBTM_PM_STATUS_CBACK* p_cb) {
101 if (std::find(btm_cb.acl_cb_.link_policy.clients.begin(),
102 btm_cb.acl_cb_.link_policy.clients.end(),
103 p_cb) != btm_cb.acl_cb_.link_policy.clients.end()) {
104 LOG_ERROR("Link policy client already registered");
105 return false;
106 }
107 btm_cb.acl_cb_.link_policy.clients.push_back(p_cb);
108 return true;
109 }
110
UnregisterLinkPolicyClient(tBTM_PM_STATUS_CBACK * p_cb)111 bool bluetooth::shim::UnregisterLinkPolicyClient(tBTM_PM_STATUS_CBACK* p_cb) {
112 auto cb = std::find(btm_cb.acl_cb_.link_policy.clients.begin(),
113 btm_cb.acl_cb_.link_policy.clients.end(), p_cb);
114 if (cb == btm_cb.acl_cb_.link_policy.clients.end()) {
115 LOG_ERROR("Link policy client already unregistered");
116 return false;
117 }
118 btm_cb.acl_cb_.link_policy.clients.erase(cb);
119 return true;
120 }
121
BTM_SetPowerMode(uint16_t handle,const tBTM_PM_PWR_MD & new_mode)122 tBTM_STATUS bluetooth::shim::BTM_SetPowerMode(uint16_t handle,
123 const tBTM_PM_PWR_MD& new_mode) {
124 tACL_CONN* p_acl = acl_get_connection_from_handle(handle);
125 if (p_acl == nullptr) {
126 return BTM_UNKNOWN_ADDR;
127 }
128
129 if (!controller_supports_link_policy_mode(
130 new_mode.mode,
131 interop_match_addr(INTEROP_DISABLE_SNIFF, &p_acl->remote_addr))) {
132 return BTM_MODE_UNSUPPORTED;
133 }
134
135 if (p_acl->policy.Mode() == new_mode.mode) {
136 LOG_INFO("Controller already in mode:%s[0x%02x]",
137 power_mode_state_text(p_acl->policy.Mode()).c_str(),
138 p_acl->policy.Mode());
139 }
140
141 if (p_acl->policy.mode.IsPending()) {
142 LOG_INFO("Link policy mode is pending");
143 }
144
145 LOG_INFO("Switching mode from %s(0x%x) to %s(0x%x)",
146 power_mode_state_text(p_acl->policy.Mode()).c_str(),
147 p_acl->policy.Mode(), power_mode_state_text(new_mode.mode).c_str(),
148 new_mode.mode);
149
150 p_acl->policy.mode.pending_ = new_mode.mode;
151 switch (new_mode.mode) {
152 case BTM_PM_MD_ACTIVE:
153 set_active_mode(*p_acl);
154 return BTM_SUCCESS;
155 break;
156 case BTM_PM_MD_SNIFF:
157 set_sniff_mode(*p_acl, new_mode.max, new_mode.min, new_mode.attempt,
158 new_mode.timeout);
159 return BTM_SUCCESS;
160 break;
161 case BTM_PM_MD_HOLD:
162 return set_hold_mode(*p_acl, new_mode.max, new_mode.min);
163 break;
164 }
165 return BTM_MODE_UNSUPPORTED;
166 }
167
is_encryption_pause_supported(const tACL_CONN & p_acl)168 static bool is_encryption_pause_supported(const tACL_CONN& p_acl) {
169 CHECK(p_acl.peer_lmp_feature_valid[0])
170 << "Checked before remote feature read has complete";
171 return HCI_ATOMIC_ENCRYPT_SUPPORTED(p_acl.peer_lmp_feature_pages[0]) &&
172 controller_get_interface()->supports_encryption_pause();
173 }
174
btm_pm_on_mode_change(tHCI_STATUS status,uint16_t handle,tHCI_MODE hci_mode,uint16_t interval)175 void bluetooth::shim::btm_pm_on_mode_change(tHCI_STATUS status, uint16_t handle,
176 tHCI_MODE hci_mode,
177 uint16_t interval) {
178 tBTM_PM_MODE new_mode = HCI_TO_BTM_POWER_MODE(hci_mode);
179
180 LOG_DEBUG(
181 "For now pointing back again to legacy status:%s handle:0x%04x "
182 "new_mode:%u interval:%u",
183 hci_error_code_text(status).c_str(), handle, new_mode, interval);
184
185 tACL_CONN* p_acl = acl_get_connection_from_handle(handle);
186 if (p_acl == nullptr) {
187 LOG_ERROR("Received mode change for unknown acl handle:0x%04x", handle);
188 return;
189 }
190
191 tBTM_PM_MODE pending = p_acl->policy.mode.Pending();
192 p_acl->policy.mode.pending_ = BTM_PM_MD_UNKNOWN;
193
194 if (status == HCI_SUCCESS) {
195 BTM_LogHistory(
196 "Power", p_acl->remote_addr, "Mode change",
197 base::StringPrintf("%s[0x%02x] ==> %s[0x%02x] pending:%s",
198 power_mode_state_text(p_acl->policy.Mode()).c_str(),
199 p_acl->policy.Mode(),
200 power_mode_state_text(new_mode).c_str(), new_mode,
201 power_mode_state_text(pending).c_str()));
202 LOG_INFO("Power mode switched from %s[%hhu] to %s[%hhu] pending:%s",
203 power_mode_state_text(p_acl->policy.Mode()).c_str(),
204 p_acl->policy.Mode(), power_mode_state_text(new_mode).c_str(),
205 new_mode, power_mode_state_text(pending).c_str());
206 p_acl->policy.mode.mode_ = new_mode;
207
208 if (new_mode == (BTM_PM_ST_ACTIVE) || new_mode == (BTM_PM_ST_SNIFF)) {
209 l2c_OnHciModeChangeSendPendingPackets(p_acl->remote_addr);
210 }
211
212 /*check if sco disconnect is waiting for the mode change */
213 btm_sco_disc_chk_pend_for_modechange(handle);
214
215 if (p_acl->is_switch_role_mode_change()) {
216 if (p_acl->is_encrypted && !is_encryption_pause_supported(*p_acl)) {
217 p_acl->set_encryption_off();
218 p_acl->set_switch_role_encryption_off();
219 } else {
220 p_acl->set_switch_role_in_progress();
221 p_acl->rs_disc_pending = BTM_SEC_RS_PENDING;
222 bluetooth::legacy::hci::GetInterface().StartRoleSwitch(
223 p_acl->remote_addr, HCI_ROLE_CENTRAL);
224 }
225 }
226 }
227
228 btm_sco_chk_pend_unpark(status, handle);
229 // btm_pm_proc_mode_change(status, handle, new_mode, interval);
230
231 for (auto client_callback : btm_cb.acl_cb_.link_policy.clients) {
232 (*client_callback)(p_acl->remote_addr, new_mode, interval, status);
233 }
234
235 LOG_DEBUG(
236 "Notified mode change registered clients cnt:%zu peer:%s "
237 "status:%s",
238 btm_cb.acl_cb_.link_policy.clients.size(),
239 PRIVATE_ADDRESS(p_acl->remote_addr), hci_error_code_text(status).c_str());
240 }
241
BTM_SetSsrParams(uint16_t handle,uint16_t max_lat,uint16_t min_rmt_to,uint16_t min_loc_to)242 tBTM_STATUS bluetooth::shim::BTM_SetSsrParams(uint16_t handle, uint16_t max_lat,
243 uint16_t min_rmt_to,
244 uint16_t min_loc_to) {
245 LOG_DEBUG("Sending gd power mode SSR Params");
246 tACL_CONN* p_acl = acl_get_connection_from_handle(handle);
247 if (p_acl == nullptr) {
248 return BTM_UNKNOWN_ADDR;
249 }
250
251 p_acl->policy.sniff_subrating.pending_ = true;
252 bluetooth::shim::Stack::GetInstance()->LinkPolicy()->SniffSubrating(
253 handle, max_lat, min_rmt_to, min_loc_to);
254 return BTM_SUCCESS;
255 }
256
btm_pm_on_sniff_subrating(tHCI_STATUS status,uint16_t handle,uint16_t maximum_transmit_latency,UNUSED_ATTR uint16_t maximum_receive_latency,uint16_t minimum_remote_timeout,uint16_t minimum_local_timeout)257 void bluetooth::shim::btm_pm_on_sniff_subrating(
258 tHCI_STATUS status, uint16_t handle, uint16_t maximum_transmit_latency,
259 UNUSED_ATTR uint16_t maximum_receive_latency,
260 uint16_t minimum_remote_timeout, uint16_t minimum_local_timeout) {
261 LOG_DEBUG("For now pointing back again to legacy");
262 tACL_CONN* p_acl = acl_get_connection_from_handle(handle);
263 if (p_acl == nullptr) {
264 LOG_ERROR("Received mode change for unknown acl handle:0x%04x", handle);
265 return;
266 }
267
268 p_acl->policy.sniff_subrating.pending_ = false;
269 if (status == HCI_SUCCESS) {
270 BTM_LogHistory(
271 "Power", p_acl->remote_addr, "Sniff Subrating",
272 base::StringPrintf(
273 "max_xmit_latency:%.2fs remote_timeout:%.2fs local_timeout:%.2fs",
274 ticks_to_seconds(maximum_transmit_latency),
275 ticks_to_seconds(minimum_remote_timeout),
276 ticks_to_seconds(minimum_local_timeout)));
277 }
278
279 const bool use_ssr =
280 (p_acl->policy.mode.Interval() != maximum_receive_latency) ? true : false;
281
282 for (auto client_callback : btm_cb.acl_cb_.link_policy.clients) {
283 (*client_callback)(p_acl->remote_addr, BTM_PM_STS_SSR, (use_ssr) ? 1 : 0,
284 status);
285 }
286
287 LOG_DEBUG(
288 "Notified sniff subrating registered clients cnt:%zu peer:%s use_ssr:%s "
289 "status:%s",
290 btm_cb.acl_cb_.link_policy.clients.size(),
291 PRIVATE_ADDRESS(p_acl->remote_addr), logbool(use_ssr).c_str(),
292 hci_error_code_text(status).c_str());
293 }
294