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