• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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