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