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