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