1 /******************************************************************************
2 *
3 * Copyright 2003-2012 Broadcom Corporation
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
19 /******************************************************************************
20 *
21 * This file contains the action functions for device manager state
22 * machine.
23 *
24 ******************************************************************************/
25
26 #include <base/functional/bind.h>
27 #include <bluetooth/log.h>
28
29 #include <cstdint>
30 #include <mutex>
31 #include <vector>
32
33 #include "bta/dm/bta_dm_int.h"
34 #include "bta/include/bta_api.h"
35 #include "bta/include/bta_dm_api.h"
36 #include "bta/sys/bta_sys.h"
37 #include "btif/include/core_callbacks.h"
38 #include "btif/include/stack_manager_t.h"
39 #include "hci/controller_interface.h"
40 #include "main/shim/dumpsys.h"
41 #include "main/shim/entry.h"
42 #include "osi/include/properties.h"
43 #include "stack/include/acl_api.h"
44 #include "stack/include/btm_client_interface.h"
45 #include "stack/include/btm_status.h"
46 #include "stack/include/main_thread.h"
47 #include "types/raw_address.h"
48
49 // TODO(b/369381361) Enfore -Wmissing-prototypes
50 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
51
52 using namespace bluetooth;
53
54 static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, const tBTA_SYS_ID id, uint8_t app_id,
55 const RawAddress& peer_addr);
56 static void bta_dm_pm_set_mode(const RawAddress& peer_addr, tBTA_DM_PM_ACTION pm_mode,
57 tBTA_DM_PM_REQ pm_req);
58 static void bta_dm_pm_timer_cback(void* data);
59 static void bta_dm_pm_btm_cback(const RawAddress& bd_addr, tBTM_PM_STATUS status, uint16_t value,
60 tHCI_STATUS hci_status);
61 static bool bta_dm_pm_park(const RawAddress& peer_addr);
62 static void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index);
63 static void bta_dm_sniff_cback(uint8_t id, uint8_t app_id, const RawAddress& peer_addr);
64 static int bta_dm_get_sco_index();
65 static void bta_dm_pm_stop_timer_by_index(tBTA_PM_TIMER* p_timer, uint8_t timer_idx);
66
67 static tBTM_PM_PWR_MD get_sniff_entry(uint8_t index);
68 static void bta_dm_pm_timer(const RawAddress& bd_addr, tBTA_DM_PM_ACTION pm_request);
69
70 #include "../hh/bta_hh_int.h"
71 /* BTA_DM_PM_SSR1 will be dedicated for HH SSR setting entry, no other profile
72 * can use it */
73 #define BTA_DM_PM_SSR_HH BTA_DM_PM_SSR1
74 static void bta_dm_pm_ssr(const RawAddress& peer_addr, const int ssr);
75
76 tBTA_DM_CONNECTED_SRVCS bta_dm_conn_srvcs;
77 static std::recursive_mutex pm_timer_schedule_mutex;
78 static std::recursive_mutex pm_timer_state_mutex;
79
80 /* Sysprop paths for sniff parameters */
81 static const char kPropertySniffMaxIntervals[] = "bluetooth.core.classic.sniff_max_intervals";
82 static const char kPropertySniffMinIntervals[] = "bluetooth.core.classic.sniff_min_intervals";
83 static const char kPropertySniffAttempts[] = "bluetooth.core.classic.sniff_attempts";
84 static const char kPropertySniffTimeouts[] = "bluetooth.core.classic.sniff_timeouts";
85
86 /*******************************************************************************
87 *
88 * Function bta_dm_init_pm
89 *
90 * Description Initializes the BT low power manager
91 *
92 *
93 * Returns void
94 *
95 ******************************************************************************/
bta_dm_init_pm(void)96 void bta_dm_init_pm(void) {
97 memset(&bta_dm_conn_srvcs, 0x00, sizeof(bta_dm_conn_srvcs));
98
99 /* if there are no power manger entries, so not register */
100 if (p_bta_dm_pm_cfg[0].app_id != 0) {
101 bta_sys_pm_register(bta_dm_pm_cback);
102 bta_sys_sniff_register(bta_dm_sniff_cback);
103
104 if (get_btm_client_interface().lifecycle.BTM_PmRegister((BTM_PM_REG_SET), &bta_dm_cb.pm_id,
105 bta_dm_pm_btm_cback) !=
106 tBTM_STATUS::BTM_SUCCESS) {
107 log::warn("Unable to initialize BTM power manager");
108 };
109 }
110
111 /* Need to initialize all PM timer service IDs */
112 for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
113 for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
114 bta_dm_cb.pm_timer[i].srvc_id[j] = BTA_ID_MAX;
115 }
116 }
117 }
118
119 /*******************************************************************************
120 *
121 * Function bta_dm_disable_pm
122 *
123 * Description Disable PM
124 *
125 *
126 * Returns void
127 *
128 ******************************************************************************/
bta_dm_disable_pm(void)129 void bta_dm_disable_pm(void) {
130 if (get_btm_client_interface().lifecycle.BTM_PmRegister(
131 BTM_PM_DEREG, &bta_dm_cb.pm_id, bta_dm_pm_btm_cback) != tBTM_STATUS::BTM_SUCCESS) {
132 log::warn("Unable to terminate BTM power manager");
133 }
134
135 /*
136 * Deregister the PM callback from the system handling to prevent
137 * re-enabling the PM timers after this call if the callback is invoked.
138 */
139 bta_sys_pm_register(NULL);
140
141 /* Need to stop all active timers. */
142 for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
143 for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
144 if (bta_dm_cb.pm_timer[i].in_use) {
145 bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], j);
146 }
147 bta_dm_cb.pm_timer[i].pm_action[j] = BTA_DM_PM_NO_ACTION;
148 }
149 }
150 }
151
152 /*******************************************************************************
153 *
154 * Function bta_dm_get_av_count
155 *
156 * Description Get the number of connected AV
157 *
158 *
159 * Returns number of av connections
160 *
161 ******************************************************************************/
bta_dm_get_av_count(void)162 uint8_t bta_dm_get_av_count(void) {
163 uint8_t count = 0;
164 for (int i = 0; i < bta_dm_conn_srvcs.count; i++) {
165 if (bta_dm_conn_srvcs.conn_srvc[i].id == BTA_ID_AV) {
166 ++count;
167 }
168 }
169 return count;
170 }
171
172 /*******************************************************************************
173 *
174 * Function bta_dm_pm_stop_timer
175 *
176 * Description stop a PM timer
177 *
178 *
179 * Returns void
180 *
181 ******************************************************************************/
bta_dm_pm_stop_timer(const RawAddress & peer_addr)182 static void bta_dm_pm_stop_timer(const RawAddress& peer_addr) {
183 log::verbose("");
184
185 for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
186 if (bta_dm_cb.pm_timer[i].in_use && bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
187 for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
188 bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], j);
189 /*
190 * TODO: For now, stopping the timer does not reset
191 * pm_action[j].
192 * The reason is because some of the internal logic that
193 * (re)assigns the pm_action[] values is taking into account
194 * the older value; e.g., see the pm_action[] assignment in
195 * function bta_dm_pm_start_timer().
196 * Such subtlety in the execution logic is error prone, and
197 * should be eliminiated in the future.
198 */
199 }
200 break;
201 }
202 }
203 }
204
205 /*******************************************************************************
206 *
207 * Function bta_pm_action_to_timer_idx
208 *
209 * Description convert power mode into timer index for each connected
210 * device
211 *
212 *
213 * Returns index of the power mode delay timer
214 *
215 ******************************************************************************/
bta_pm_action_to_timer_idx(uint8_t pm_action)216 static uint8_t bta_pm_action_to_timer_idx(uint8_t pm_action) {
217 if (pm_action == BTA_DM_PM_SUSPEND) {
218 return BTA_DM_PM_SUSPEND_TIMER_IDX;
219 } else if (pm_action == BTA_DM_PM_PARK) {
220 return BTA_DM_PM_PARK_TIMER_IDX;
221 } else if ((pm_action & BTA_DM_PM_SNIFF) == BTA_DM_PM_SNIFF) {
222 return BTA_DM_PM_SNIFF_TIMER_IDX;
223 }
224
225 /* Active, no preference, no action and retry */
226 return BTA_DM_PM_MODE_TIMER_MAX;
227 }
228
229 /*******************************************************************************
230 *
231 * Function bta_dm_pm_stop_timer_by_mode
232 *
233 * Description stop a PM timer
234 *
235 *
236 * Returns void
237 *
238 ******************************************************************************/
bta_dm_pm_stop_timer_by_mode(const RawAddress & peer_addr,uint8_t power_mode)239 static void bta_dm_pm_stop_timer_by_mode(const RawAddress& peer_addr, uint8_t power_mode) {
240 const uint8_t timer_idx = bta_pm_action_to_timer_idx(power_mode);
241 if (timer_idx == BTA_DM_PM_MODE_TIMER_MAX) {
242 return;
243 }
244
245 for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
246 if (bta_dm_cb.pm_timer[i].in_use && bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
247 if (bta_dm_cb.pm_timer[i].srvc_id[timer_idx] != BTA_ID_MAX) {
248 bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], timer_idx);
249 /*
250 * TODO: Intentionally setting pm_action[timer_idx].
251 * This assignment should be eliminated in the future - see the
252 * pm_action[] related comment inside function
253 * bta_dm_pm_stop_timer().
254 */
255 bta_dm_cb.pm_timer[i].pm_action[timer_idx] = power_mode;
256 }
257 break;
258 }
259 }
260 }
261
262 /*******************************************************************************
263 *
264 * Function bta_dm_pm_stop_timer_by_srvc_id
265 *
266 * Description stop all timer started by the service ID.
267 *
268 *
269 * Returns index of the power mode delay timer
270 *
271 ******************************************************************************/
bta_dm_pm_stop_timer_by_srvc_id(const RawAddress & peer_addr,uint8_t srvc_id)272 static void bta_dm_pm_stop_timer_by_srvc_id(const RawAddress& peer_addr, uint8_t srvc_id) {
273 for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
274 if (bta_dm_cb.pm_timer[i].in_use && bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
275 for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
276 if (bta_dm_cb.pm_timer[i].srvc_id[j] == srvc_id) {
277 bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], j);
278 bta_dm_cb.pm_timer[i].pm_action[j] = BTA_DM_PM_NO_ACTION;
279 break;
280 }
281 }
282 }
283 }
284 }
285
286 /*******************************************************************************
287 *
288 * Function bta_dm_pm_start_timer
289 *
290 * Description start a PM timer
291 *
292 *
293 * Returns void
294 *
295 ******************************************************************************/
bta_dm_pm_start_timer(tBTA_PM_TIMER * p_timer,uint8_t timer_idx,uint64_t timeout_ms,uint8_t srvc_id,uint8_t pm_action)296 static void bta_dm_pm_start_timer(tBTA_PM_TIMER* p_timer, uint8_t timer_idx, uint64_t timeout_ms,
297 uint8_t srvc_id, uint8_t pm_action) {
298 std::unique_lock<std::recursive_mutex> schedule_lock(pm_timer_schedule_mutex);
299 std::unique_lock<std::recursive_mutex> state_lock(pm_timer_state_mutex);
300 p_timer->in_use = true;
301
302 if (p_timer->srvc_id[timer_idx] == BTA_ID_MAX) {
303 p_timer->active++;
304 }
305
306 if (p_timer->pm_action[timer_idx] < pm_action) {
307 p_timer->pm_action[timer_idx] = pm_action;
308 }
309
310 p_timer->srvc_id[timer_idx] = srvc_id;
311 state_lock.unlock();
312
313 alarm_set_on_mloop(p_timer->timer[timer_idx], timeout_ms, bta_dm_pm_timer_cback,
314 p_timer->timer[timer_idx]);
315 }
316
317 /*******************************************************************************
318 *
319 * Function bta_dm_pm_stop_timer_by_index
320 *
321 * Description stop a PM timer
322 *
323 *
324 * Returns void
325 *
326 ******************************************************************************/
bta_dm_pm_stop_timer_by_index(tBTA_PM_TIMER * p_timer,uint8_t timer_idx)327 static void bta_dm_pm_stop_timer_by_index(tBTA_PM_TIMER* p_timer, uint8_t timer_idx) {
328 if ((p_timer == NULL) || (timer_idx >= BTA_DM_PM_MODE_TIMER_MAX)) {
329 return;
330 }
331
332 std::unique_lock<std::recursive_mutex> schedule_lock(pm_timer_schedule_mutex);
333 std::unique_lock<std::recursive_mutex> state_lock(pm_timer_state_mutex);
334 if (p_timer->srvc_id[timer_idx] == BTA_ID_MAX) {
335 return;
336 } /* The timer was not scheduled */
337
338 log::assert_that(p_timer->in_use, "Timer was not scheduled p_timer->srvc_id[timer_idx]:{}",
339 p_timer->srvc_id[timer_idx]);
340 log::assert_that(p_timer->active > 0, "No tasks on timer are active");
341
342 p_timer->srvc_id[timer_idx] = BTA_ID_MAX;
343 /* NOTE: pm_action[timer_idx] intentionally not reset */
344
345 p_timer->active--;
346 if (p_timer->active == 0) {
347 p_timer->in_use = false;
348 }
349 state_lock.unlock();
350
351 alarm_cancel(p_timer->timer[timer_idx]);
352 }
353
354 /*******************************************************************************
355 *
356 * Function bta_dm_sniff_cback
357 *
358 * Description Restart sniff timer for a peer
359 *
360 *
361 * Returns void
362 *
363 ******************************************************************************/
bta_dm_sniff_cback(uint8_t id,uint8_t app_id,const RawAddress & peer_addr)364 static void bta_dm_sniff_cback(uint8_t id, uint8_t app_id, const RawAddress& peer_addr) {
365 int i = 0, j = 0;
366 uint64_t timeout_ms = 0;
367
368 tBTA_DM_PEER_DEVICE* p_peer_device = bta_dm_find_peer_device(peer_addr);
369 if (p_peer_device == NULL) {
370 log::info("No peer device found: {}", peer_addr);
371 return;
372 }
373
374 /* Search for sniff table for timeout value
375 p_bta_dm_pm_cfg[0].app_id is the number of entries */
376 for (j = 1; j <= p_bta_dm_pm_cfg[0].app_id; j++) {
377 if ((p_bta_dm_pm_cfg[j].id == id) &&
378 ((p_bta_dm_pm_cfg[j].app_id == BTA_ALL_APP_ID) || (p_bta_dm_pm_cfg[j].app_id == app_id))) {
379 break;
380 }
381 }
382 // Handle overflow access
383 if (j > p_bta_dm_pm_cfg[0].app_id) {
384 log::info("No configuration found for {}", peer_addr);
385 return;
386 }
387 const tBTA_DM_PM_CFG* p_pm_cfg = &p_bta_dm_pm_cfg[j];
388 const tBTA_DM_PM_SPEC* p_pm_spec = &get_bta_dm_pm_spec()[p_pm_cfg->spec_idx];
389 const tBTA_DM_PM_ACTN* p_act0 = &p_pm_spec->actn_tbl[BTA_SYS_CONN_IDLE][0];
390 const tBTA_DM_PM_ACTN* p_act1 = &p_pm_spec->actn_tbl[BTA_SYS_CONN_IDLE][1];
391
392 tBTA_DM_PM_ACTION failed_pm = p_peer_device->pm_mode_failed;
393 /* first check if the first preference is ok */
394 if (!(failed_pm & p_act0->power_mode)) {
395 timeout_ms = p_act0->timeout;
396 } else if (!(failed_pm & p_act1->power_mode)) {
397 /* if first preference has already failed, try second preference */
398 timeout_ms = p_act1->timeout;
399 }
400
401 /* Refresh the sniff timer */
402 for (i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
403 if (bta_dm_cb.pm_timer[i].in_use && bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
404 int timer_idx = bta_pm_action_to_timer_idx(BTA_DM_PM_SNIFF);
405 if (timer_idx != BTA_DM_PM_MODE_TIMER_MAX) {
406 /* Cancel and restart the timer */
407 bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], timer_idx);
408 bta_dm_pm_start_timer(&bta_dm_cb.pm_timer[i], timer_idx, timeout_ms, id, BTA_DM_PM_SNIFF);
409 }
410 }
411 }
412 }
413
414 /*******************************************************************************
415 *
416 * Function bta_dm_pm_cback
417 *
418 * Description Conn change callback from sys for low power management
419 *
420 *
421 * Returns void
422 *
423 ******************************************************************************/
bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status,const tBTA_SYS_ID id,uint8_t app_id,const RawAddress & peer_addr)424 static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, const tBTA_SYS_ID id, uint8_t app_id,
425 const RawAddress& peer_addr) {
426 uint8_t i, j;
427 tBTA_DM_PEER_DEVICE* p_dev;
428 tBTA_DM_PM_REQ pm_req = BTA_DM_PM_NEW_REQ;
429
430 log::verbose("Power management callback status:{}[{}] id:{}[{}], app:{}",
431 bta_sys_conn_status_text(status), status, BtaIdSysText(id), id, app_id);
432
433 /* find if there is an power mode entry for the service */
434 for (i = 1; i <= p_bta_dm_pm_cfg[0].app_id; i++) {
435 if ((p_bta_dm_pm_cfg[i].id == id) &&
436 ((p_bta_dm_pm_cfg[i].app_id == BTA_ALL_APP_ID) || (p_bta_dm_pm_cfg[i].app_id == app_id))) {
437 break;
438 }
439 }
440
441 /* if no entries are there for the app_id and subsystem in
442 * get_bta_dm_pm_spec()*/
443 if (i > p_bta_dm_pm_cfg[0].app_id) {
444 log::debug("Ignoring power management callback as no service entries exist");
445 return;
446 }
447
448 log::verbose("Stopped all timers for service to device:{} id:{}[{}]", peer_addr, BtaIdSysText(id),
449 id);
450 bta_dm_pm_stop_timer_by_srvc_id(peer_addr, static_cast<uint8_t>(id));
451
452 p_dev = bta_dm_find_peer_device(peer_addr);
453 if (p_dev) {
454 log::verbose("Device info:{}", p_dev->info_text());
455 } else {
456 log::error("Unable to find peer device...yet soldiering on...");
457 }
458
459 /* set SSR parameters on SYS CONN OPEN */
460 int index = BTA_DM_PM_SSR0;
461 if ((BTA_SYS_CONN_OPEN == status) && p_dev && (p_dev->is_ssr_active())) {
462 index = get_bta_dm_pm_spec()[p_bta_dm_pm_cfg[i].spec_idx].ssr;
463 } else if (BTA_ID_AV == id) {
464 if (BTA_SYS_CONN_BUSY == status) {
465 /* set SSR4 for A2DP on SYS CONN BUSY */
466 index = BTA_DM_PM_SSR4;
467 } else if (BTA_SYS_CONN_IDLE == status) {
468 index = get_bta_dm_pm_spec()[p_bta_dm_pm_cfg[i].spec_idx].ssr;
469 }
470 }
471
472 /* if no action for the event */
473 if (get_bta_dm_pm_spec()[p_bta_dm_pm_cfg[i].spec_idx].actn_tbl[status][0].power_mode ==
474 BTA_DM_PM_NO_ACTION) {
475 if (BTA_DM_PM_SSR0 == index) { /* and do not need to set SSR, return. */
476 return;
477 }
478 }
479
480 for (j = 0; j < bta_dm_conn_srvcs.count; j++) {
481 /* check if an entry already present */
482 if ((bta_dm_conn_srvcs.conn_srvc[j].id == id) &&
483 (bta_dm_conn_srvcs.conn_srvc[j].app_id == app_id) &&
484 bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr == peer_addr) {
485 bta_dm_conn_srvcs.conn_srvc[j].new_request = true;
486 break;
487 }
488 }
489
490 /* if subsystem has no more preference on the power mode remove
491 the cb */
492 if (get_bta_dm_pm_spec()[p_bta_dm_pm_cfg[i].spec_idx].actn_tbl[status][0].power_mode ==
493 BTA_DM_PM_NO_PREF) {
494 if (j != bta_dm_conn_srvcs.count) {
495 bta_dm_conn_srvcs.count--;
496
497 for (; j < bta_dm_conn_srvcs.count; j++) {
498 memcpy(&bta_dm_conn_srvcs.conn_srvc[j], &bta_dm_conn_srvcs.conn_srvc[j + 1],
499 sizeof(bta_dm_conn_srvcs.conn_srvc[j]));
500 }
501 } else {
502 log::warn("bta_dm_act no entry for connected service cbs");
503 return;
504 }
505 } else if (j == bta_dm_conn_srvcs.count) {
506 /* check if we have more connected service that cbs */
507 if (bta_dm_conn_srvcs.count == BTA_DM_NUM_CONN_SRVS) {
508 log::warn("bta_dm_act no more connected service cbs");
509 return;
510 }
511
512 /* fill in a new cb */
513 bta_dm_conn_srvcs.conn_srvc[j].id = id;
514 bta_dm_conn_srvcs.conn_srvc[j].app_id = app_id;
515 bta_dm_conn_srvcs.conn_srvc[j].new_request = true;
516 bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr = peer_addr;
517
518 log::info("New connection service:{}[{}] app_id:{}", BtaIdSysText(id), id, app_id);
519
520 bta_dm_conn_srvcs.count++;
521 bta_dm_conn_srvcs.conn_srvc[j].state = status;
522 } else {
523 /* no service is added or removed. only updating status. */
524 bta_dm_conn_srvcs.conn_srvc[j].state = status;
525 }
526
527 /* stop timer */
528 bta_dm_pm_stop_timer(peer_addr);
529 if (bta_dm_conn_srvcs.count > 0) {
530 pm_req = BTA_DM_PM_RESTART;
531 log::verbose(
532 "bta_dm_pm_stop_timer for current service, restart other service "
533 "timers: count = {}",
534 bta_dm_conn_srvcs.count);
535 }
536
537 if (p_dev) {
538 p_dev->pm_mode_attempted = 0;
539 p_dev->pm_mode_failed = 0;
540 }
541
542 if (p_bta_dm_ssr_spec[index].max_lat || index == BTA_DM_PM_SSR_HH) {
543 /* do not perform ssr for AVDTP start */
544 if (id != BTA_ID_AV || status != BTA_SYS_CONN_BUSY) {
545 bta_dm_pm_ssr(peer_addr, index);
546 } else {
547 log::debug("Do not perform SSR when AVDTP start");
548 }
549 } else {
550 uint8_t* p = NULL;
551 if (bluetooth::shim::GetController()->SupportsSniffSubrating() &&
552 ((NULL != (p = get_btm_client_interface().peer.BTM_ReadRemoteFeatures(peer_addr))) &&
553 HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
554 (index == BTA_DM_PM_SSR0)) {
555 if (status == BTA_SYS_SCO_OPEN) {
556 log::verbose("SCO inactive, reset SSR to zero");
557 if (get_btm_client_interface().link_policy.BTM_SetSsrParams(peer_addr, 0, 0, 0) !=
558 tBTM_STATUS::BTM_SUCCESS) {
559 log::warn("Unable to set link into sniff mode peer:{}", peer_addr);
560 }
561 } else if (status == BTA_SYS_SCO_CLOSE) {
562 log::verbose("SCO active, back to old SSR");
563 bta_dm_pm_ssr(peer_addr, BTA_DM_PM_SSR0);
564 }
565 }
566 }
567
568 bta_dm_pm_set_mode(peer_addr, BTA_DM_PM_NO_ACTION, pm_req);
569 }
570
571 /*******************************************************************************
572 *
573 * Function bta_dm_pm_set_mode
574 *
575 * Description Set the power mode for the device
576 *
577 *
578 * Returns void
579 *
580 ******************************************************************************/
581
bta_dm_pm_set_mode(const RawAddress & peer_addr,tBTA_DM_PM_ACTION pm_request,tBTA_DM_PM_REQ pm_req)582 static void bta_dm_pm_set_mode(const RawAddress& peer_addr, tBTA_DM_PM_ACTION pm_request,
583 tBTA_DM_PM_REQ pm_req) {
584 tBTA_DM_PM_ACTION pm_action = BTA_DM_PM_NO_ACTION;
585 uint64_t timeout_ms = 0;
586 uint8_t i, j;
587 tBTA_DM_PM_ACTION failed_pm = 0;
588 tBTA_DM_PEER_DEVICE* p_peer_device = NULL;
589 tBTA_DM_PM_ACTION allowed_modes = 0;
590 tBTA_DM_PM_ACTION pref_modes = 0;
591 const tBTA_DM_PM_CFG* p_pm_cfg;
592 const tBTA_DM_PM_SPEC* p_pm_spec;
593 const tBTA_DM_PM_ACTN* p_act0;
594 const tBTA_DM_PM_ACTN* p_act1;
595 tBTA_DM_SRVCS* p_srvcs = NULL;
596 bool timer_started = false;
597 uint8_t timer_idx, available_timer = BTA_DM_PM_MODE_TIMER_MAX;
598 uint64_t remaining_ms = 0;
599
600 if (!bta_dm_cb.device_list.count) {
601 log::info("Device list count is zero");
602 return;
603 }
604
605 /* see if any attempt to put device in low power mode failed */
606 p_peer_device = bta_dm_find_peer_device(peer_addr);
607 /* if no peer device found return */
608 if (p_peer_device == NULL) {
609 log::info("No peer device found");
610 return;
611 }
612
613 failed_pm = p_peer_device->pm_mode_failed;
614
615 for (i = 0; i < bta_dm_conn_srvcs.count; i++) {
616 p_srvcs = &bta_dm_conn_srvcs.conn_srvc[i];
617 if (p_srvcs->peer_bdaddr == peer_addr) {
618 /* p_bta_dm_pm_cfg[0].app_id is the number of entries */
619 for (j = 1; j <= p_bta_dm_pm_cfg[0].app_id; j++) {
620 if ((p_bta_dm_pm_cfg[j].id == p_srvcs->id) &&
621 ((p_bta_dm_pm_cfg[j].app_id == BTA_ALL_APP_ID) ||
622 (p_bta_dm_pm_cfg[j].app_id == p_srvcs->app_id))) {
623 break;
624 }
625 }
626
627 p_pm_cfg = &p_bta_dm_pm_cfg[j];
628 p_pm_spec = &get_bta_dm_pm_spec()[p_pm_cfg->spec_idx];
629 p_act0 = &p_pm_spec->actn_tbl[p_srvcs->state][0];
630 p_act1 = &p_pm_spec->actn_tbl[p_srvcs->state][1];
631
632 allowed_modes |= p_pm_spec->allow_mask;
633 log::verbose("Service:{}[{}] state:{}[{}] allowed_modes:0x{:02x} service_index:{}",
634 BtaIdSysText(p_srvcs->id), p_srvcs->id, bta_sys_conn_status_text(p_srvcs->state),
635 p_srvcs->state, allowed_modes, j);
636
637 /* PM actions are in the order of strictness */
638
639 /* first check if the first preference is ok */
640 if (!(failed_pm & p_act0->power_mode)) {
641 pref_modes |= p_act0->power_mode;
642
643 if (p_act0->power_mode >= pm_action) {
644 pm_action = p_act0->power_mode;
645
646 if (pm_req != BTA_DM_PM_NEW_REQ || p_srvcs->new_request) {
647 p_srvcs->new_request = false;
648 timeout_ms = p_act0->timeout;
649 }
650 }
651 } else if (!(failed_pm & p_act1->power_mode)) {
652 /* if first preference has already failed, try second preference */
653 pref_modes |= p_act1->power_mode;
654
655 if (p_act1->power_mode > pm_action) {
656 pm_action = p_act1->power_mode;
657 timeout_ms = p_act1->timeout;
658 }
659 }
660 }
661 }
662
663 if (pm_action & (BTA_DM_PM_PARK | BTA_DM_PM_SNIFF)) {
664 /* some service don't like the mode */
665 if (!(allowed_modes & pm_action)) {
666 /* select the other mode if its allowed and preferred, otherwise 0 which
667 * is BTA_DM_PM_NO_ACTION */
668 pm_action = (allowed_modes & (BTA_DM_PM_PARK | BTA_DM_PM_SNIFF) & pref_modes);
669
670 /* no timeout needed if no action is required */
671 if (pm_action == BTA_DM_PM_NO_ACTION) {
672 timeout_ms = 0;
673 }
674 }
675 }
676 /* if need to start a timer */
677 if ((pm_req != BTA_DM_PM_EXECUTE) && (timeout_ms > 0)) {
678 for (i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
679 if (bta_dm_cb.pm_timer[i].in_use && bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
680 timer_idx = bta_pm_action_to_timer_idx(pm_action);
681 if (timer_idx != BTA_DM_PM_MODE_TIMER_MAX) {
682 remaining_ms = alarm_get_remaining_ms(bta_dm_cb.pm_timer[i].timer[timer_idx]);
683 if (remaining_ms < timeout_ms) {
684 /* Cancel and restart the timer */
685 /*
686 * TODO: The value of pm_action[timer_idx] is
687 * conditionally updated between the two function
688 * calls below when the timer is restarted.
689 * This logic is error-prone and should be eliminated
690 * in the future.
691 */
692 bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], timer_idx);
693 bta_dm_pm_start_timer(&bta_dm_cb.pm_timer[i], timer_idx, timeout_ms, p_srvcs->id,
694 pm_action);
695 }
696 timer_started = true;
697 }
698 break;
699 } else if (!bta_dm_cb.pm_timer[i].in_use) {
700 if (available_timer == BTA_DM_PM_MODE_TIMER_MAX) {
701 available_timer = i;
702 }
703 }
704 }
705 /* new power mode for a new active connection */
706 if (!timer_started) {
707 if (available_timer != BTA_DM_PM_MODE_TIMER_MAX) {
708 bta_dm_cb.pm_timer[available_timer].peer_bdaddr = peer_addr;
709 timer_idx = bta_pm_action_to_timer_idx(pm_action);
710 if (timer_idx != BTA_DM_PM_MODE_TIMER_MAX) {
711 bta_dm_pm_start_timer(&bta_dm_cb.pm_timer[available_timer], timer_idx, timeout_ms,
712 p_srvcs->id, pm_action);
713 timer_started = true;
714 }
715 } else {
716 log::warn("no more timers");
717 }
718 }
719 return;
720 }
721 /* if pending power mode timer expires, and currecnt link is in a
722 lower power mode than current profile requirement, igonre it */
723 if (pm_req == BTA_DM_PM_EXECUTE && pm_request < pm_action) {
724 log::error("Ignore the power mode request: {}", pm_request);
725 return;
726 }
727 if (pm_action == BTA_DM_PM_PARK) {
728 p_peer_device->pm_mode_attempted = BTA_DM_PM_PARK;
729 bta_dm_pm_park(peer_addr);
730 log::warn("DEPRECATED Setting link to park mode peer:{}", peer_addr);
731 } else if (pm_action & BTA_DM_PM_SNIFF) {
732 /* dont initiate SNIFF, if link_policy has it disabled */
733 if (BTM_is_sniff_allowed_for(peer_addr)) {
734 log::verbose("Link policy allows sniff mode so setting mode peer:{}", peer_addr);
735 p_peer_device->pm_mode_attempted = BTA_DM_PM_SNIFF;
736 bta_dm_pm_sniff(p_peer_device, (uint8_t)(pm_action & 0x0F));
737 } else {
738 log::debug("Link policy disallows sniff mode, ignore request peer:{}", peer_addr);
739 }
740 } else if (pm_action == BTA_DM_PM_ACTIVE) {
741 log::verbose("Setting link to active mode peer:{}", peer_addr);
742 bta_dm_pm_active(peer_addr);
743 }
744 }
745 /*******************************************************************************
746 *
747 * Function bta_ag_pm_park
748 *
749 * Description Switch to park mode.
750 *
751 *
752 * Returns true if park attempted, false otherwise.
753 *
754 ******************************************************************************/
bta_dm_pm_park(const RawAddress & peer_addr)755 static bool bta_dm_pm_park(const RawAddress& peer_addr) {
756 tBTM_PM_MODE mode = BTM_PM_STS_ACTIVE;
757
758 /* if not in park mode, switch to park */
759 if (!BTM_ReadPowerMode(peer_addr, &mode)) {
760 log::warn("Unable to read power mode for peer:{}", peer_addr);
761 }
762
763 if (mode != BTM_PM_MD_PARK) {
764 tBTM_STATUS status = get_btm_client_interface().link_policy.BTM_SetPowerMode(
765 bta_dm_cb.pm_id, peer_addr, &p_bta_dm_pm_md[BTA_DM_PM_PARK_IDX]);
766 if (status == tBTM_STATUS::BTM_CMD_STORED || status == tBTM_STATUS::BTM_CMD_STARTED) {
767 return true;
768 }
769 log::warn("Unable to set park power mode");
770 }
771 return true;
772 }
773 /*******************************************************************************
774 *
775 * Function get_sniff_entry
776 *
777 * Description Helper function to get sniff entry from sysprop or
778 * default table.
779 *
780 *
781 * Returns tBTM_PM_PWR_MD with specified |index|.
782 *
783 ******************************************************************************/
get_sniff_entry(uint8_t index)784 static tBTM_PM_PWR_MD get_sniff_entry(uint8_t index) {
785 static std::vector<tBTM_PM_PWR_MD> pwr_mds_cache;
786 if (pwr_mds_cache.size() == BTA_DM_PM_PARK_IDX) {
787 if (index >= BTA_DM_PM_PARK_IDX) {
788 return pwr_mds_cache[0];
789 }
790 return pwr_mds_cache[index];
791 }
792
793 std::vector<uint32_t> invalid_list(BTA_DM_PM_PARK_IDX, 0);
794 std::vector<uint32_t> max = osi_property_get_uintlist(kPropertySniffMaxIntervals, invalid_list);
795 std::vector<uint32_t> min = osi_property_get_uintlist(kPropertySniffMinIntervals, invalid_list);
796 std::vector<uint32_t> attempt = osi_property_get_uintlist(kPropertySniffAttempts, invalid_list);
797 std::vector<uint32_t> timeout = osi_property_get_uintlist(kPropertySniffTimeouts, invalid_list);
798
799 // If any of the sysprops are malformed or don't exist, use default table
800 // value
801 bool use_defaults = (max.size() < BTA_DM_PM_PARK_IDX || max == invalid_list ||
802 min.size() < BTA_DM_PM_PARK_IDX || min == invalid_list ||
803 attempt.size() < BTA_DM_PM_PARK_IDX || attempt == invalid_list ||
804 timeout.size() < BTA_DM_PM_PARK_IDX || timeout == invalid_list);
805
806 for (auto i = 0; i < BTA_DM_PM_PARK_IDX; i++) {
807 if (use_defaults) {
808 pwr_mds_cache.push_back(p_bta_dm_pm_md[i]);
809 } else {
810 pwr_mds_cache.push_back(tBTM_PM_PWR_MD{static_cast<uint16_t>(max[i]),
811 static_cast<uint16_t>(min[i]),
812 static_cast<uint16_t>(attempt[i]),
813 static_cast<uint16_t>(timeout[i]), BTM_PM_MD_SNIFF});
814 }
815 }
816
817 if (index >= BTA_DM_PM_PARK_IDX) {
818 return pwr_mds_cache[0];
819 }
820 return pwr_mds_cache[index];
821 }
822 /*******************************************************************************
823 *
824 * Function bta_ag_pm_sniff
825 *
826 * Description Switch to sniff mode.
827 *
828 *
829 * Returns true if sniff attempted, false otherwise.
830 *
831 ******************************************************************************/
bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE * p_peer_dev,uint8_t index)832 static void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index) {
833 tBTM_PM_MODE mode = BTM_PM_MD_ACTIVE;
834 tBTM_PM_PWR_MD pwr_md;
835 tBTM_STATUS status;
836
837 if (!BTM_ReadPowerMode(p_peer_dev->peer_bdaddr, &mode)) {
838 log::warn("Unable to read power mode for peer:{}", p_peer_dev->peer_bdaddr);
839 }
840 tBTM_PM_STATUS mode_status = static_cast<tBTM_PM_STATUS>(mode);
841 log::debug("Current power mode:{}[0x{:x}] peer_info:{}", power_mode_status_text(mode_status),
842 mode_status, p_peer_dev->info_text());
843
844 uint8_t* p_rem_feat =
845 get_btm_client_interface().peer.BTM_ReadRemoteFeatures(p_peer_dev->peer_bdaddr);
846
847 if (mode != BTM_PM_MD_SNIFF ||
848 (bluetooth::shim::GetController()->SupportsSniffSubrating() && p_rem_feat &&
849 HCI_SNIFF_SUB_RATE_SUPPORTED(p_rem_feat) && !(p_peer_dev->is_ssr_active()))) {
850 /* Dont initiate Sniff if controller has alreay accepted
851 * remote sniff params. This avoid sniff loop issue with
852 * some agrresive headsets who use sniff latencies more than
853 * DUT supported range of Sniff intervals.*/
854 if ((mode == BTM_PM_MD_SNIFF) && (p_peer_dev->is_remote_init_sniff())) {
855 log::debug("Link already in sniff mode peer:{}", p_peer_dev->peer_bdaddr);
856 return;
857 }
858 }
859 /* if the current mode is not sniff, issue the sniff command.
860 * If sniff, but SSR is not used in this link, still issue the command */
861 tBTM_PM_PWR_MD sniff_entry = get_sniff_entry(index);
862 memcpy(&pwr_md, &sniff_entry, sizeof(tBTM_PM_PWR_MD));
863 if (p_peer_dev->is_local_init_sniff()) {
864 log::debug("Trying to force power mode");
865 pwr_md.mode |= BTM_PM_MD_FORCE;
866 }
867 status = get_btm_client_interface().link_policy.BTM_SetPowerMode(
868 bta_dm_cb.pm_id, p_peer_dev->peer_bdaddr, &pwr_md);
869 if (status == tBTM_STATUS::BTM_CMD_STORED || status == tBTM_STATUS::BTM_CMD_STARTED) {
870 p_peer_dev->reset_sniff_flags();
871 p_peer_dev->set_sniff_command_sent();
872 } else if (status == tBTM_STATUS::BTM_SUCCESS) {
873 log::verbose("bta_dm_pm_sniff BTM_SetPowerMode() returns tBTM_STATUS::BTM_SUCCESS");
874 p_peer_dev->reset_sniff_flags();
875 } else {
876 log::error("Unable to set power mode peer:{} status:{}", p_peer_dev->peer_bdaddr,
877 btm_status_text(status));
878 p_peer_dev->reset_sniff_flags();
879 }
880 }
881 /*******************************************************************************
882 *
883 * Function bta_dm_pm_ssr
884 *
885 * Description checks and sends SSR parameters
886 *
887 * Returns void
888 *
889 ******************************************************************************/
bta_dm_pm_ssr(const RawAddress & peer_addr,const int ssr)890 static void bta_dm_pm_ssr(const RawAddress& peer_addr, const int ssr) {
891 int ssr_index = ssr;
892 tBTA_DM_SSR_SPEC* p_spec = &p_bta_dm_ssr_spec[ssr];
893
894 log::debug("Request to put link to device:{} into power_mode:{}", peer_addr, p_spec->name);
895 /* go through the connected services */
896 for (int i = 0; i < bta_dm_conn_srvcs.count; i++) {
897 const tBTA_DM_SRVCS& service = bta_dm_conn_srvcs.conn_srvc[i];
898 if (service.peer_bdaddr != peer_addr) {
899 continue;
900 }
901 /* p_bta_dm_pm_cfg[0].app_id is the number of entries */
902 int current_ssr_index = BTA_DM_PM_SSR0;
903 for (int j = 1; j <= p_bta_dm_pm_cfg[0].app_id; j++) {
904 /* find the associated p_bta_dm_pm_cfg */
905 const tBTA_DM_PM_CFG& config = p_bta_dm_pm_cfg[j];
906 current_ssr_index = get_bta_dm_pm_spec()[config.spec_idx].ssr;
907 if ((config.id == service.id) &&
908 ((config.app_id == BTA_ALL_APP_ID) || (config.app_id == service.app_id))) {
909 log::info("Found connected service:{} app_id:{} peer:{} spec_name:{}",
910 BtaIdSysText(service.id), service.app_id, peer_addr,
911 p_bta_dm_ssr_spec[current_ssr_index].name);
912 break;
913 }
914 }
915 /* find the ssr index with the smallest max latency. */
916 tBTA_DM_SSR_SPEC* p_spec_cur = &p_bta_dm_ssr_spec[current_ssr_index];
917 /* HH has the per connection SSR preference, already read the SSR params
918 * from BTA HH */
919 if (current_ssr_index == BTA_DM_PM_SSR_HH) {
920 tAclLinkSpec link_spec;
921 link_spec.addrt.bda = peer_addr;
922 link_spec.addrt.type = BLE_ADDR_PUBLIC;
923 link_spec.transport = BT_TRANSPORT_BR_EDR;
924 if (GetInterfaceToProfiles()->profileSpecific_HACK->bta_hh_read_ssr_param(
925 link_spec, &p_spec_cur->max_lat, &p_spec_cur->min_rmt_to) == BTA_HH_ERR) {
926 continue;
927 }
928 }
929 if (p_spec_cur->max_lat < p_spec->max_lat ||
930 (ssr_index == BTA_DM_PM_SSR0 && current_ssr_index != BTA_DM_PM_SSR0)) {
931 log::debug(
932 "Changing sniff subrating specification for {} from {}[{}] ==> "
933 "{}[{}]",
934 peer_addr, p_spec->name, ssr_index, p_spec_cur->name, current_ssr_index);
935 ssr_index = current_ssr_index;
936 p_spec = &p_bta_dm_ssr_spec[ssr_index];
937 }
938 }
939
940 if (p_spec->max_lat) {
941 /* Avoid SSR reset on device which has SCO connected */
942 int idx = bta_dm_get_sco_index();
943 if (idx != -1) {
944 if (bta_dm_conn_srvcs.conn_srvc[idx].peer_bdaddr == peer_addr) {
945 log::warn("SCO is active on device, ignore SSR");
946 return;
947 }
948 }
949
950 log::debug(
951 "Setting sniff subrating for device:{} spec_name:{} "
952 "max_latency(s):{:.2f} min_local_timeout(s):{:.2f} "
953 "min_remote_timeout(s):{:.2f}",
954 peer_addr, p_spec->name, ticks_to_seconds(p_spec->max_lat),
955 ticks_to_seconds(p_spec->min_loc_to), ticks_to_seconds(p_spec->min_rmt_to));
956 /* set the SSR parameters. */
957 if (get_btm_client_interface().link_policy.BTM_SetSsrParams(
958 peer_addr, p_spec->max_lat, p_spec->min_rmt_to, p_spec->min_loc_to) !=
959 tBTM_STATUS::BTM_SUCCESS) {
960 log::warn("Unable to set link into sniff mode peer:{}", peer_addr);
961 }
962 }
963 }
964
965 /*******************************************************************************
966 *
967 * Function bta_dm_pm_active
968 *
969 * Description Brings connection to active mode
970 *
971 * Returns void
972 *
973 ******************************************************************************/
bta_dm_pm_active(const RawAddress & peer_addr)974 void bta_dm_pm_active(const RawAddress& peer_addr) {
975 tBTM_PM_PWR_MD pm{
976 .mode = BTM_PM_MD_ACTIVE,
977 };
978
979 /* switch to active mode */
980 tBTM_STATUS status =
981 get_btm_client_interface().link_policy.BTM_SetPowerMode(bta_dm_cb.pm_id, peer_addr, &pm);
982 switch (status) {
983 case tBTM_STATUS::BTM_CMD_STORED:
984 log::debug("Active power mode stored for execution later for remote:{}", peer_addr);
985 break;
986 case tBTM_STATUS::BTM_CMD_STARTED:
987 log::debug("Active power mode started for remote:{}", peer_addr);
988 break;
989 case tBTM_STATUS::BTM_SUCCESS:
990 log::debug("Active power mode already set for device:{}", peer_addr);
991 break;
992 default:
993 log::warn("Unable to set active power mode for device:{} status:{}", peer_addr,
994 btm_status_text(status));
995 break;
996 }
997 }
998
999 static void bta_dm_pm_btm_status(const RawAddress& bd_addr, tBTM_PM_STATUS status,
1000 uint16_t interval, tHCI_STATUS hci_status);
1001
1002 /** BTM power manager callback */
bta_dm_pm_btm_cback(const RawAddress & bd_addr,tBTM_PM_STATUS status,uint16_t value,tHCI_STATUS hci_status)1003 static void bta_dm_pm_btm_cback(const RawAddress& bd_addr, tBTM_PM_STATUS status, uint16_t value,
1004 tHCI_STATUS hci_status) {
1005 do_in_main_thread(base::BindOnce(bta_dm_pm_btm_status, bd_addr, status, value, hci_status));
1006 }
1007
1008 /*******************************************************************************
1009 *
1010 * Function bta_dm_pm_timer_cback
1011 *
1012 * Description Power management timer callback.
1013 *
1014 *
1015 * Returns void
1016 *
1017 ******************************************************************************/
bta_dm_pm_timer_cback(void * data)1018 static void bta_dm_pm_timer_cback(void* data) {
1019 uint8_t i, j;
1020 alarm_t* alarm = (alarm_t*)data;
1021
1022 std::unique_lock<std::recursive_mutex> state_lock(pm_timer_state_mutex);
1023 for (i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
1024 log::verbose("dm_pm_timer[{}] in use? {}", i, bta_dm_cb.pm_timer[i].in_use);
1025 if (bta_dm_cb.pm_timer[i].in_use) {
1026 for (j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
1027 if (bta_dm_cb.pm_timer[i].timer[j] == alarm) {
1028 bta_dm_cb.pm_timer[i].active--;
1029 bta_dm_cb.pm_timer[i].srvc_id[j] = BTA_ID_MAX;
1030 log::verbose("dm_pm_timer[{}] expires, timer_idx={}", i, j);
1031 break;
1032 }
1033 }
1034 if (bta_dm_cb.pm_timer[i].active == 0) {
1035 bta_dm_cb.pm_timer[i].in_use = false;
1036 }
1037 if (j < BTA_DM_PM_MODE_TIMER_MAX) {
1038 break;
1039 }
1040 }
1041 }
1042 state_lock.unlock();
1043
1044 /* no more timers */
1045 if (i == BTA_DM_NUM_PM_TIMER) {
1046 return;
1047 }
1048
1049 do_in_main_thread(base::BindOnce(bta_dm_pm_timer, bta_dm_cb.pm_timer[i].peer_bdaddr,
1050 bta_dm_cb.pm_timer[i].pm_action[j]));
1051 }
1052
1053 /** Process pm status event from btm */
bta_dm_pm_btm_status(const RawAddress & bd_addr,tBTM_PM_STATUS status,uint16_t interval,tHCI_STATUS hci_status)1054 static void bta_dm_pm_btm_status(const RawAddress& bd_addr, tBTM_PM_STATUS status,
1055 uint16_t interval, tHCI_STATUS hci_status) {
1056 log::verbose(
1057 "Power mode notification event status:{} peer:{} interval:{} "
1058 "hci_status:{}",
1059 power_mode_status_text(status), bd_addr, interval, hci_error_code_text(hci_status));
1060
1061 tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr);
1062 if (p_dev == nullptr) {
1063 log::info("Unable to process power event for peer:{}", bd_addr);
1064 return;
1065 }
1066
1067 /* check new mode */
1068 switch (status) {
1069 case BTM_PM_STS_ACTIVE:
1070 /* if our sniff or park attempt failed
1071 we should not try it again*/
1072 if (hci_status != 0) {
1073 log::error("hci_status={}", hci_status);
1074 p_dev->reset_sniff_flags();
1075
1076 if (p_dev->pm_mode_attempted & (BTA_DM_PM_PARK | BTA_DM_PM_SNIFF)) {
1077 p_dev->pm_mode_failed |= ((BTA_DM_PM_PARK | BTA_DM_PM_SNIFF) & p_dev->pm_mode_attempted);
1078 bta_dm_pm_stop_timer_by_mode(bd_addr, p_dev->pm_mode_attempted);
1079 bta_dm_pm_set_mode(bd_addr, BTA_DM_PM_NO_ACTION, BTA_DM_PM_RESTART);
1080 }
1081 } else {
1082 if (p_dev->prev_low) {
1083 /* need to send the SSR paramaters to controller again */
1084 bta_dm_pm_ssr(p_dev->peer_bdaddr, BTA_DM_PM_SSR0);
1085 }
1086 p_dev->prev_low = BTM_PM_STS_ACTIVE;
1087 /* link to active mode, need to restart the timer for next low power
1088 * mode if needed */
1089 bta_dm_pm_stop_timer(bd_addr);
1090 bta_dm_pm_set_mode(bd_addr, BTA_DM_PM_NO_ACTION, BTA_DM_PM_RESTART);
1091 }
1092 break;
1093
1094 case BTM_PM_STS_PARK:
1095 case BTM_PM_STS_HOLD:
1096 /* save the previous low power mode - for SSR.
1097 * SSR parameters are sent to controller on "conn open".
1098 * the numbers stay good until park/hold/detach */
1099 if (p_dev->is_ssr_active()) {
1100 p_dev->prev_low = status;
1101 }
1102 break;
1103
1104 case BTM_PM_STS_SSR:
1105 if (hci_status != 0) {
1106 log::warn("Received error when attempting to set sniff subrating mode");
1107 }
1108 if (interval) {
1109 p_dev->set_ssr_active();
1110 log::debug("Enabling sniff subrating mode for peer:{}", bd_addr);
1111 } else {
1112 p_dev->reset_ssr_active();
1113 log::debug("Disabling sniff subrating mode for peer:{}", bd_addr);
1114 }
1115 break;
1116 case BTM_PM_STS_SNIFF:
1117 if (hci_status == 0) {
1118 /* Stop PM timer now if already active for
1119 * particular device since link is already
1120 * put in sniff mode by remote device, and
1121 * PM timer sole purpose is to put the link
1122 * in sniff mode from host side.
1123 */
1124 bta_dm_pm_stop_timer(bd_addr);
1125 } else {
1126 bool is_sniff_command_sent = p_dev->is_sniff_command_sent();
1127 p_dev->reset_sniff_flags();
1128 if (is_sniff_command_sent) {
1129 p_dev->set_local_init_sniff();
1130 } else {
1131 p_dev->set_remote_init_sniff();
1132 }
1133 }
1134 break;
1135
1136 case BTM_PM_STS_ERROR:
1137 p_dev->reset_sniff_command_sent();
1138 break;
1139 case BTM_PM_STS_PENDING:
1140 break;
1141
1142 default:
1143 log::error("Received unknown power mode status event:{}", status);
1144 break;
1145 }
1146 }
1147
1148 /** Process pm timer event from btm */
bta_dm_pm_timer(const RawAddress & bd_addr,tBTA_DM_PM_ACTION pm_request)1149 static void bta_dm_pm_timer(const RawAddress& bd_addr, tBTA_DM_PM_ACTION pm_request) {
1150 log::verbose("");
1151 bta_dm_pm_set_mode(bd_addr, pm_request, BTA_DM_PM_EXECUTE);
1152 }
1153
1154 /*******************************************************************************
1155 *
1156 * Function bta_dm_find_peer_device
1157 *
1158 * Description Given an address, find the associated control block.
1159 *
1160 * Returns tBTA_DM_PEER_DEVICE
1161 *
1162 ******************************************************************************/
bta_dm_find_peer_device(const RawAddress & peer_addr)1163 tBTA_DM_PEER_DEVICE* bta_dm_find_peer_device(const RawAddress& peer_addr) {
1164 tBTA_DM_PEER_DEVICE* p_dev = NULL;
1165
1166 for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
1167 if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == peer_addr) {
1168 p_dev = &bta_dm_cb.device_list.peer_device[i];
1169 break;
1170 }
1171 }
1172 return p_dev;
1173 }
1174
1175 /*******************************************************************************
1176 *
1177 * Function bta_dm_get_sco_index
1178 *
1179 * Description Loop through connected services for HFP+State=SCO
1180 *
1181 * Returns index at which SCO is connected, in absence of SCO return -1
1182 *
1183 ******************************************************************************/
bta_dm_get_sco_index()1184 static int bta_dm_get_sco_index() {
1185 for (int j = 0; j < bta_dm_conn_srvcs.count; j++) {
1186 /* check for SCO connected index */
1187 if ((bta_dm_conn_srvcs.conn_srvc[j].id == BTA_ID_AG) &&
1188 (bta_dm_conn_srvcs.conn_srvc[j].state == BTA_SYS_SCO_OPEN)) {
1189 return j;
1190 }
1191 }
1192 return -1;
1193 }
1194
1195 /*******************************************************************************
1196 *
1197 * Function bta_dm_pm_obtain_controller_state
1198 *
1199 * Description This function obtains the consolidated controller power
1200 * state
1201 *
1202 * Parameters:
1203 *
1204 ******************************************************************************/
bta_dm_pm_obtain_controller_state(void)1205 tBTM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void) {
1206 /* Did not use counts as it is not sure, how accurate the count values are
1207 *in
1208 ** bta_dm_cb.device_list.count > 0 || bta_dm_cb.device_list.le_count > 0 */
1209
1210 tBTM_CONTRL_STATE cur_state = BTM_CONTRL_UNKNOWN;
1211 cur_state = BTM_PM_ReadControllerState();
1212
1213 log::verbose("bta_dm_pm_obtain_controller_state: {}", cur_state);
1214 return cur_state;
1215 }
1216