1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <base/strings/stringprintf.h>
20 
21 #include <cstdint>
22 #include <string>
23 
24 #include "stack/include/btm_status.h"
25 #include "stack/include/hci_error_code.h"
26 #include "stack/include/hci_mode.h"
27 #include "types/raw_address.h"
28 
29 /* BTM Power manager status codes */
30 enum : uint8_t {
31   BTM_PM_STS_ACTIVE = HCI_MODE_ACTIVE,  // 0x00
32   BTM_PM_STS_HOLD = HCI_MODE_HOLD,      // 0x01
33   BTM_PM_STS_SNIFF = HCI_MODE_SNIFF,    // 0x02
34   BTM_PM_STS_PARK = HCI_MODE_PARK,      // 0x03
35   BTM_PM_STS_SSR,     /* report the SSR parameters in HCI_SNIFF_SUB_RATE_EVT */
36   BTM_PM_STS_PENDING, /* when waiting for status from controller */
37   BTM_PM_STS_ERROR    /* when HCI command status returns error */
38 };
39 typedef uint8_t tBTM_PM_STATUS;
40 
power_mode_status_text(tBTM_PM_STATUS status)41 inline std::string power_mode_status_text(tBTM_PM_STATUS status) {
42   switch (status) {
43     case BTM_PM_STS_ACTIVE:
44       return std::string("active");
45     case BTM_PM_STS_HOLD:
46       return std::string("hold");
47     case BTM_PM_STS_SNIFF:
48       return std::string("sniff");
49     case BTM_PM_STS_PARK:
50       return std::string("park");
51     case BTM_PM_STS_SSR:
52       return std::string("sniff_subrating");
53     case BTM_PM_STS_PENDING:
54       return std::string("pending");
55     case BTM_PM_STS_ERROR:
56       return std::string("error");
57     default:
58       return std::string("UNKNOWN");
59   }
60 }
61 
62 /* BTM Power manager modes */
63 enum : uint8_t {
64   BTM_PM_MD_ACTIVE = HCI_MODE_ACTIVE,  // 0x00
65   BTM_PM_MD_HOLD = HCI_MODE_HOLD,      // 0x01
66   BTM_PM_MD_SNIFF = HCI_MODE_SNIFF,    // 0x02
67   BTM_PM_MD_PARK = HCI_MODE_PARK,      // 0x03
68   BTM_PM_MD_FORCE = 0x10, /* OR this to force ACL link to a certain mode */
69   BTM_PM_MD_UNKNOWN = 0xEF,
70 };
71 
72 typedef uint8_t tBTM_PM_MODE;
73 #define HCI_TO_BTM_POWER_MODE(mode) (static_cast<tBTM_PM_MODE>(mode))
74 
is_legal_power_mode(tBTM_PM_MODE mode)75 inline bool is_legal_power_mode(tBTM_PM_MODE mode) {
76   switch (mode & ~BTM_PM_MD_FORCE) {
77     case BTM_PM_MD_ACTIVE:
78     case BTM_PM_MD_HOLD:
79     case BTM_PM_MD_SNIFF:
80     case BTM_PM_MD_PARK:
81       return true;
82     default:
83       return false;
84   }
85 }
86 
power_mode_text(tBTM_PM_MODE mode)87 inline std::string power_mode_text(tBTM_PM_MODE mode) {
88   std::string s = base::StringPrintf((mode & BTM_PM_MD_FORCE) ? "" : "forced:");
89   switch (mode & ~BTM_PM_MD_FORCE) {
90     case BTM_PM_MD_ACTIVE:
91       return s + std::string("active");
92     case BTM_PM_MD_HOLD:
93       return s + std::string("hold");
94     case BTM_PM_MD_SNIFF:
95       return s + std::string("sniff");
96     case BTM_PM_MD_PARK:
97       return s + std::string("park");
98     default:
99       return s + std::string("UNKNOWN");
100   }
101 }
102 
103 #define BTM_PM_SET_ONLY_ID 0x80
104 
105 /* Operation codes */
106 typedef enum : uint8_t {
107   /* The module wants to set the desired power mode */
108   BTM_PM_REG_SET = (1u << 0),
109   /* The module does not want to involve with PM anymore */
110   BTM_PM_DEREG = (1u << 2),
111 } tBTM_PM_REGISTER;
112 
113 typedef struct {
114   uint16_t max = 0;
115   uint16_t min = 0;
116   uint16_t attempt = 0;
117   uint16_t timeout = 0;
118   tBTM_PM_MODE mode = BTM_PM_MD_ACTIVE;  // 0
119 } tBTM_PM_PWR_MD;
120 
121 typedef void(tBTM_PM_STATUS_CBACK)(const RawAddress& p_bda,
122                                    tBTM_PM_STATUS status, uint16_t value,
123                                    tHCI_STATUS hci_status);
124 
125 #define BTM_CONTRL_UNKNOWN 0
126 /* ACL link on, SCO link ongoing, sniff mode */
127 #define BTM_CONTRL_ACTIVE 1
128 /* Scan state - paging/inquiry/trying to connect*/
129 #define BTM_CONTRL_SCAN 2
130 /* Idle state - page scan, LE advt, inquiry scan */
131 #define BTM_CONTRL_IDLE 3
132 
133 #define BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_MASK 0xF
134 #define BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_SHIFT 0
135 #define BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_MASK 0xF
136 #define BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_SHIFT 4
137 #define BTM_CONTRL_NUM_ACL_LE_MASK 0xF
138 #define BTM_CONTRL_NUM_ACL_LE_SHIFT 8
139 #define BTM_CONTRL_NUM_LE_ADV_MASK 0xF
140 #define BTM_CONTRL_NUM_LE_ADV_SHIFT 12
141 
142 #define BTM_CONTRL_LE_SCAN_MODE_IDLE 0
143 #define BTM_CONTRL_LE_SCAN_MODE_ULTRA_LOW_POWER 1
144 #define BTM_CONTRL_LE_SCAN_MODE_LOW_POWER 2
145 #define BTM_CONTRL_LE_SCAN_MODE_BALANCED 3
146 #define BTM_CONTRL_LE_SCAN_MODE_LOW_LATENCY 4
147 #define BTM_CONTRL_LE_SCAN_MODE_MASK 0xF
148 #define BTM_CONTRL_LE_SCAN_MODE_SHIFT 16
149 
150 #define BTM_CONTRL_INQUIRY_SHIFT 20
151 #define BTM_CONTRL_INQUIRY (1u << BTM_CONTRL_INQUIRY_SHIFT)
152 #define BTM_CONTRL_SCO_SHIFT 21
153 #define BTM_CONTRL_SCO (1u << BTM_CONTRL_SCO_SHIFT)
154 #define BTM_CONTRL_A2DP_SHIFT 22
155 #define BTM_CONTRL_A2DP (1u << BTM_CONTRL_A2DP_SHIFT)
156 #define BTM_CONTRL_LE_AUDIO_SHIFT 23
157 #define BTM_CONTRL_LE_AUDIO (1u << BTM_CONTRL_LE_AUDIO_SHIFT)
158 
159 typedef uint32_t tBTM_CONTRL_STATE;
160 
set_num_acl_active_to_ctrl_state(uint32_t num,tBTM_CONTRL_STATE & ctrl_state)161 inline void set_num_acl_active_to_ctrl_state(uint32_t num,
162                                              tBTM_CONTRL_STATE& ctrl_state) {
163   if (num > BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_MASK) {
164     num = BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_MASK;
165   }
166   ctrl_state |= ((num & BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_MASK)
167                  << BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_SHIFT);
168 }
169 
set_num_acl_sniff_to_ctrl_state(uint32_t num,tBTM_CONTRL_STATE & ctrl_state)170 inline void set_num_acl_sniff_to_ctrl_state(uint32_t num,
171                                             tBTM_CONTRL_STATE& ctrl_state) {
172   if (num > BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_MASK) {
173     num = BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_MASK;
174   }
175   ctrl_state |= ((num & BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_MASK)
176                  << BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_SHIFT);
177 }
178 
set_num_acl_le_to_ctrl_state(uint32_t num,tBTM_CONTRL_STATE & ctrl_state)179 inline void set_num_acl_le_to_ctrl_state(uint32_t num,
180                                          tBTM_CONTRL_STATE& ctrl_state) {
181   if (num > BTM_CONTRL_NUM_ACL_LE_MASK) {
182     num = BTM_CONTRL_NUM_ACL_LE_MASK;
183   }
184   ctrl_state |=
185       ((num & BTM_CONTRL_NUM_ACL_LE_MASK) << BTM_CONTRL_NUM_ACL_LE_SHIFT);
186 }
187 
set_num_le_adv_to_ctrl_state(uint32_t num,tBTM_CONTRL_STATE & ctrl_state)188 inline void set_num_le_adv_to_ctrl_state(uint32_t num,
189                                          tBTM_CONTRL_STATE& ctrl_state) {
190   if (num > BTM_CONTRL_NUM_LE_ADV_MASK) {
191     num = BTM_CONTRL_NUM_LE_ADV_MASK;
192   }
193   ctrl_state |=
194       ((num & BTM_CONTRL_NUM_LE_ADV_MASK) << BTM_CONTRL_NUM_LE_ADV_SHIFT);
195 }
196 
set_le_scan_mode_to_ctrl_state(uint32_t duty_cycle,tBTM_CONTRL_STATE & ctrl_state)197 inline void set_le_scan_mode_to_ctrl_state(uint32_t duty_cycle,
198                                            tBTM_CONTRL_STATE& ctrl_state) {
199   uint32_t scan_mode;
200   if (duty_cycle == 0) {
201     scan_mode = BTM_CONTRL_LE_SCAN_MODE_IDLE;
202   } else if (duty_cycle <= 5) {
203     scan_mode = BTM_CONTRL_LE_SCAN_MODE_ULTRA_LOW_POWER;
204   } else if (duty_cycle <= 10) {
205     scan_mode = BTM_CONTRL_LE_SCAN_MODE_LOW_POWER;
206   } else if (duty_cycle <= 25) {
207     scan_mode = BTM_CONTRL_LE_SCAN_MODE_BALANCED;
208   } else {
209     scan_mode = BTM_CONTRL_LE_SCAN_MODE_LOW_LATENCY;
210   }
211   ctrl_state |= ((scan_mode & BTM_CONTRL_LE_SCAN_MODE_MASK)
212                  << BTM_CONTRL_LE_SCAN_MODE_SHIFT);
213 }
214 
215 /*******************************************************************************
216  *
217  * Function         BTM_PmRegister
218  *
219  * Description      register or deregister with power manager
220  *
221  * Returns          BTM_SUCCESS if successful,
222  *                  BTM_NO_RESOURCES if no room to hold registration
223  *                  BTM_ILLEGAL_VALUE
224  *
225  ******************************************************************************/
226 tBTM_STATUS BTM_PmRegister(uint8_t mask, uint8_t* p_pm_id,
227                            tBTM_PM_STATUS_CBACK* p_cb);
228 
229 // Notified by ACL that a new link is connected
230 void BTM_PM_OnConnected(uint16_t handle, const RawAddress& remote_bda);
231 
232 // Notified by ACL that a link is disconnected
233 void BTM_PM_OnDisconnected(uint16_t handle);
234 
235 /*******************************************************************************
236  *
237  * Function         BTM_SetPowerMode
238  *
239  * Description      store the mode in control block or
240  *                  alter ACL connection behavior.
241  *
242  * Returns          BTM_SUCCESS if successful,
243  *                  BTM_UNKNOWN_ADDR if bd addr is not active or bad
244  *
245  ******************************************************************************/
246 tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda,
247                              const tBTM_PM_PWR_MD* p_mode);
248 bool BTM_SetLinkPolicyActiveMode(const RawAddress& remote_bda);
249 
250 /*******************************************************************************
251  *
252  * Function         BTM_SetSsrParams
253  *
254  * Description      This sends the given SSR parameters for the given ACL
255  *                  connection if it is in ACTIVE mode.
256  *
257  * Input Param      remote_bda - device address of desired ACL connection
258  *                  max_lat    - maximum latency (in 0.625ms)(0-0xFFFE)
259  *                  min_rmt_to - minimum remote timeout
260  *                  min_loc_to - minimum local timeout
261  *
262  *
263  * Returns          BTM_SUCCESS if the HCI command is issued successful,
264  *                  BTM_UNKNOWN_ADDR if bd addr is not active or bad
265  *                  BTM_CMD_STORED if the command is stored
266  *
267  ******************************************************************************/
268 tBTM_STATUS BTM_SetSsrParams(const RawAddress& remote_bda, uint16_t max_lat,
269                              uint16_t min_rmt_to, uint16_t min_loc_to);
270 
271 /*******************************************************************************
272  *
273  * Function         BTM_PM_ReadControllerState
274  *
275  * Description      This function is called to obtain the controller state
276  *
277  * Returns          Controller state (BTM_CONTRL_ACTIVE, BTM_CONTRL_SCAN, and
278  *                                    BTM_CONTRL_IDLE)
279  *
280  ******************************************************************************/
281 tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void);
282 
283 /*******************************************************************************
284  *
285  * Function         BTM_PM_ReadSniffLinkCount
286  *
287  * Description      Return the number of BT connection in sniff mode
288  *
289  * Returns          Number of BT connection in sniff mode
290  *
291  ******************************************************************************/
292 uint8_t BTM_PM_ReadSniffLinkCount(void);
293 
294 /*******************************************************************************
295  *
296  * Function         BTM_PM_ReadBleLinkCount
297  *
298  * Description      Return the number of BLE connection
299  *
300  * Returns          Number of BLE connection
301  *
302  ******************************************************************************/
303 uint8_t BTM_PM_ReadBleLinkCount(void);
304 
305 /*******************************************************************************
306  *
307  * Function         BTM_PM_DeviceInScanState
308  *
309  * Description      This function is called to check if in inquiry
310  *
311  * Returns          true, if in inquiry
312  *
313  ******************************************************************************/
314 bool BTM_PM_DeviceInScanState(void);
315 
316 /*******************************************************************************
317  *
318  * Function         BTM_PM_ReadBleScanDutyCycle
319  *
320  * Description      Returns BLE scan duty cycle which is (window * 100) /
321  *interval
322  *
323  * Returns          BLE scan duty cycle
324  *
325  ******************************************************************************/
326 uint32_t BTM_PM_ReadBleScanDutyCycle(void);
327