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