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