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