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