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