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