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