1 /*
2 * Copyright 2020 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 <bluetooth/log.h>
20
21 #include <cstdint>
22
23 #include "internal_include/bt_target.h"
24 #include "macros.h"
25 #include "osi/include/alarm.h"
26 #include "stack/btm/btm_eir.h"
27 #include "stack/include/bt_device_type.h"
28 #include "stack/include/bt_name.h"
29 #include "stack/include/btm_api_types.h"
30 #include "stack/include/btm_status.h"
31 #include "types/ble_address_with_type.h"
32 #include "types/raw_address.h"
33
34 /* Discoverable modes */
35 enum : uint16_t {
36 BTM_NON_DISCOVERABLE = 0,
37 BTM_LIMITED_DISCOVERABLE = (1 << 0),
38 BTM_GENERAL_DISCOVERABLE = (1 << 1),
39 BTM_MAX_DISCOVERABLE = BTM_GENERAL_DISCOVERABLE,
40 BTM_DISCOVERABLE_MASK = (BTM_LIMITED_DISCOVERABLE | BTM_GENERAL_DISCOVERABLE),
41 /* high byte for BLE Discoverable modes */
42 BTM_BLE_NON_DISCOVERABLE = 0x0000,
43 BTM_BLE_LIMITED_DISCOVERABLE = 0x0100,
44 BTM_BLE_GENERAL_DISCOVERABLE = 0x0200,
45 BTM_BLE_MAX_DISCOVERABLE = BTM_BLE_GENERAL_DISCOVERABLE,
46 BTM_BLE_DISCOVERABLE_MASK =
47 (BTM_BLE_LIMITED_DISCOVERABLE | BTM_BLE_GENERAL_DISCOVERABLE),
48 };
49
50 /* Connectable modes */
51 enum : uint16_t {
52 BTM_NON_CONNECTABLE = 0,
53 BTM_CONNECTABLE = (1 << 0),
54 BTM_CONNECTABLE_MASK = (BTM_NON_CONNECTABLE | BTM_CONNECTABLE),
55 /* high byte for BLE Connectable modes */
56 BTM_BLE_NON_CONNECTABLE = BTM_NON_CONNECTABLE,
57 BTM_BLE_CONNECTABLE = 0x0100,
58 BTM_BLE_MAX_CONNECTABLE = BTM_BLE_CONNECTABLE,
59 BTM_BLE_CONNECTABLE_MASK = (BTM_BLE_NON_CONNECTABLE | BTM_BLE_CONNECTABLE),
60 };
61
62 /* Inquiry modes
63 * Note: These modes are associated with the inquiry active values (BTM_*ACTIVE)
64 */
65 enum : uint8_t {
66 BTM_INQUIRY_INACTIVE = 0x0,
67 BTM_GENERAL_INQUIRY = 0x01,
68 /* high nibble of inquiry mode for BLE inquiry mode */
69 BTM_BLE_GENERAL_INQUIRY = 0x10,
70 /* inquiry activity mask */
71 BTM_INQUIRY_ACTIVE_MASK = (BTM_GENERAL_INQUIRY | BTM_BLE_GENERAL_INQUIRY),
72 };
73
74 /* Define scan types */
75 enum : uint16_t {
76 BTM_SCAN_TYPE_STANDARD = 0,
77 BTM_SCAN_TYPE_INTERLACED = 1, /* 1.2 devices only */
78 };
79
80 /* Define inquiry results mode */
81 typedef enum : uint8_t {
82 BTM_INQ_RESULT_STANDARD = 0,
83 BTM_INQ_RESULT_WITH_RSSI = 1,
84 BTM_INQ_RESULT_EXTENDED = 2,
85 /* RSSI value not supplied (ignore it) */
86 BTM_INQ_RES_IGNORE_RSSI = 0x7f,
87 } tBTM_INQ_RESULT;
88 constexpr size_t kMaxNumberInquiryResults = BTM_INQ_RESULT_EXTENDED + 1;
89
90 /* These are the fields returned in each device's response to the inquiry. It
91 * is returned in the results callback if registered.
92 */
93 typedef struct {
94 uint16_t clock_offset;
95 RawAddress remote_bd_addr;
96 DEV_CLASS dev_class;
97 uint8_t page_scan_rep_mode;
98 uint8_t page_scan_per_mode;
99 uint8_t page_scan_mode;
100 int8_t rssi; /* Set to BTM_INQ_RES_IGNORE_RSSI if not valid */
101 uint32_t eir_uuid[BTM_EIR_SERVICE_ARRAY_SIZE];
102 bool eir_complete_list;
103 tBT_DEVICE_TYPE device_type;
104 uint8_t inq_result_type;
105 tBLE_ADDR_TYPE ble_addr_type;
106 uint16_t ble_evt_type;
107 uint8_t ble_primary_phy;
108 uint8_t ble_secondary_phy;
109 uint8_t ble_advertising_sid;
110 int8_t ble_tx_power;
111 uint16_t ble_periodic_adv_int;
112 RawAddress ble_ad_rsi; /* Resolvable Set Identifier from advertising */
113 bool ble_ad_is_le_audio_capable;
114 uint8_t flag;
115 bool include_rsi;
116 RawAddress original_bda;
117 } tBTM_INQ_RESULTS;
118
119 /****************************************
120 * Device Discovery Callback Functions
121 ****************************************/
122 /* Callback function for notifications when the BTM gets inquiry response.
123 * First param is inquiry results database, second is pointer of EIR.
124 */
125 typedef void(tBTM_INQ_RESULTS_CB)(tBTM_INQ_RESULTS* p_inq_results,
126 const uint8_t* p_eir, uint16_t eir_len);
127
128 typedef struct {
129 uint32_t inq_count; /* Used for determining if a response has already been */
130 /* received for the current inquiry operation. (We do not */
131 /* want to flood the caller with multiple responses from */
132 /* the same device. */
133 RawAddress bd_addr;
134 } tINQ_BDADDR;
135
136 /* This is the inquiry response information held in its database by BTM, and
137 * available to applications via BTM_InqDbRead, BTM_InqDbFirst, and
138 * BTM_InqDbNext.
139 */
140 typedef struct {
141 tBTM_INQ_RESULTS results;
142
143 bool appl_knows_rem_name; /* set by application if it knows the remote name of
144 the peer device.
145 This is later used by application to determine if
146 remote name request is
147 required to be done. Having the flag here avoid
148 duplicate store of inquiry results */
149 uint16_t remote_name_len;
150 BD_NAME remote_name;
151 uint8_t remote_name_type;
152 } tBTM_INQ_INFO;
153
154 typedef struct {
155 uint64_t time_of_resp;
156 uint32_t
157 inq_count; /* "timestamps" the entry with a particular inquiry count */
158 /* Used for determining if a response has already been */
159 /* received for the current inquiry operation. (We do not */
160 /* want to flood the caller with multiple responses from */
161 /* the same device. */
162 tBTM_INQ_INFO inq_info;
163 bool in_use;
164 bool scan_rsp;
165 } tINQ_DB_ENT;
166
167 typedef struct /* contains the parameters passed to the inquiry functions */
168 {
169 uint8_t mode; /* general or limited */
170 uint8_t duration; /* duration of the inquiry (1.28 sec increments) */
171 } tBTM_INQ_PARMS;
172
173 /* Structure returned with inquiry complete callback */
174 typedef struct {
175 // Possible inquiry completion status
176 enum STATUS {
177 CANCELED, // Expected user API cancel
178 TIMER_POPPED, // Expected controller initiated timeout
179 NOT_STARTED, // Unexpected controller unable to execute inquiry command
180 SSP_ACTIVE, // Unexpected secure simple pairing is operational
181 };
182 STATUS status;
183 tHCI_STATUS hci_status;
184 uint8_t num_resp; /* Number of results from the current inquiry */
185 unsigned resp_type[kMaxNumberInquiryResults];
186 long long start_time_ms;
187 } tBTM_INQUIRY_CMPL;
188
btm_inquiry_cmpl_status_text(const tBTM_INQUIRY_CMPL::STATUS & status)189 inline std::string btm_inquiry_cmpl_status_text(
190 const tBTM_INQUIRY_CMPL::STATUS& status) {
191 switch (status) {
192 CASE_RETURN_TEXT(tBTM_INQUIRY_CMPL::CANCELED);
193 CASE_RETURN_TEXT(tBTM_INQUIRY_CMPL::TIMER_POPPED);
194 CASE_RETURN_TEXT(tBTM_INQUIRY_CMPL::NOT_STARTED);
195 CASE_RETURN_TEXT(tBTM_INQUIRY_CMPL::SSP_ACTIVE);
196 default:
197 return std::string("UNKNOWN[") + std::to_string(status) +
198 std::string("]");
199 }
200 }
201
202 /* Structure returned with remote name request */
203 typedef struct {
204 tBTM_STATUS status;
205 RawAddress bd_addr;
206 BD_NAME remote_bd_name;
207 tHCI_STATUS hci_status;
208 } tBTM_REMOTE_DEV_NAME;
209
210 typedef void(tBTM_NAME_CMPL_CB)(const tBTM_REMOTE_DEV_NAME*);
211
212 struct tBTM_INQUIRY_VAR_ST {
213 tBTM_NAME_CMPL_CB* p_remname_cmpl_cb;
214
215 alarm_t* remote_name_timer;
216 alarm_t* classic_inquiry_timer;
217
218 uint16_t discoverable_mode;
219 uint16_t connectable_mode;
220 uint16_t page_scan_window;
221 uint16_t page_scan_period;
222 uint16_t inq_scan_window;
223 uint16_t inq_scan_period;
224 uint16_t inq_scan_type;
225 uint16_t page_scan_type; /* current page scan type */
226
227 RawAddress remname_bda; /* Name of bd addr for active remote name request */
228 bool remname_active; /* State of a remote name request by external API */
229 tBT_DEVICE_TYPE remname_dev_type; /* Whether it's LE or BREDR name request */
230
231 tBTM_CMPL_CB* p_inq_cmpl_cb;
232 tBTM_INQ_RESULTS_CB* p_inq_results_cb;
233 uint32_t inq_counter; /* Counter incremented each time an inquiry completes */
234 /* Used for determining whether or not duplicate devices */
235 /* have responded to the same inquiry */
236 tBTM_INQ_PARMS inqparms; /* Contains the parameters for the current inquiry */
237 tBTM_INQUIRY_CMPL
238 inq_cmpl_info; /* Status and number of responses from the last inquiry */
239
240 uint16_t per_min_delay; /* Current periodic minimum delay */
241 uint16_t per_max_delay; /* Current periodic maximum delay */
242 /* inquiry that has been cancelled*/
243 uint8_t inqfilt_type; /* Contains the inquiry filter type (BD ADDR, COD, or
244 Clear) */
245
246 #define BTM_INQ_INACTIVE_STATE 0
247 #define BTM_INQ_ACTIVE_STATE \
248 3 /* Actual inquiry or periodic inquiry is in progress */
249
250 uint8_t state; /* Current state that the inquiry process is in */
251 uint8_t inq_active; /* Bit Mask indicating type of inquiry is active */
252
253 bool registered_for_hci_events;
254
InittBTM_INQUIRY_VAR_ST255 void Init() {
256 p_remname_cmpl_cb = nullptr;
257
258 alarm_free(remote_name_timer);
259 alarm_free(classic_inquiry_timer);
260 remote_name_timer = alarm_new("btm_inq.remote_name_timer");
261 classic_inquiry_timer = alarm_new("btm_inq.classic_inquiry_timer");
262
263 discoverable_mode = BTM_NON_DISCOVERABLE;
264 connectable_mode = BTM_NON_CONNECTABLE;
265
266 page_scan_window = HCI_DEF_PAGESCAN_WINDOW;
267 page_scan_period = HCI_DEF_PAGESCAN_INTERVAL;
268 inq_scan_window = HCI_DEF_INQUIRYSCAN_WINDOW;
269 inq_scan_period = HCI_DEF_INQUIRYSCAN_INTERVAL;
270 inq_scan_type = BTM_SCAN_TYPE_STANDARD;
271 page_scan_type = HCI_DEF_SCAN_TYPE;
272
273 remname_bda = {};
274 remname_active = false;
275 remname_dev_type = BT_DEVICE_TYPE_UNKNOWN;
276
277 p_inq_cmpl_cb = nullptr;
278 p_inq_results_cb = nullptr;
279
280 inq_counter = 0;
281 inqparms = {};
282 inq_cmpl_info = {};
283
284 per_min_delay = 0;
285 per_max_delay = 0;
286 state = BTM_INQ_INACTIVE_STATE;
287 inq_active = 0;
288 registered_for_hci_events = false;
289 }
FreetBTM_INQUIRY_VAR_ST290 void Free() {
291 alarm_free(remote_name_timer);
292 alarm_free(classic_inquiry_timer);
293 }
294 };
295
296 bool btm_inq_find_bdaddr(const RawAddress& p_bda);
297 tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda);
298
299 namespace fmt {
300 template <>
301 struct formatter<tBTM_INQUIRY_CMPL::STATUS>
302 : enum_formatter<tBTM_INQUIRY_CMPL::STATUS> {};
303 } // namespace fmt
304