1/******************************************************************************
2 *
3 *  Copyright (C) 2016 The Android Open Source Project
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19#define LOG_TAG "bt_btif_scanner"
20
21#include <base/bind.h>
22#include <base/threading/thread.h>
23#include <errno.h>
24#include <hardware/bluetooth.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unordered_set>
29#include "device/include/controller.h"
30
31#include "btif_common.h"
32#include "btif_util.h"
33
34#include <hardware/bt_gatt.h>
35
36#include "advertise_data_parser.h"
37#include "bta_api.h"
38#include "bta_closure_api.h"
39#include "bta_gatt_api.h"
40#include "btif_config.h"
41#include "btif_dm.h"
42#include "btif_gatt.h"
43#include "btif_gatt_util.h"
44#include "btif_storage.h"
45#include "osi/include/log.h"
46#include "vendor_api.h"
47
48using base::Bind;
49using base::Owned;
50using std::vector;
51using RegisterCallback = BleScannerInterface::RegisterCallback;
52
53extern const btgatt_callbacks_t* bt_gatt_callbacks;
54
55#define SCAN_CBACK_IN_JNI(P_CBACK, ...)                              \
56  do {                                                               \
57    if (bt_gatt_callbacks && bt_gatt_callbacks->scanner->P_CBACK) {  \
58      BTIF_TRACE_API("HAL bt_gatt_callbacks->client->%s", #P_CBACK); \
59      do_in_jni_thread(                                              \
60          Bind(bt_gatt_callbacks->scanner->P_CBACK, __VA_ARGS__));   \
61    } else {                                                         \
62      ASSERTC(0, "Callback is NULL", 0);                             \
63    }                                                                \
64  } while (0)
65
66namespace {
67
68// all access to this variable should be done on the jni thread
69std::set<RawAddress> remote_bdaddr_cache;
70std::queue<RawAddress> remote_bdaddr_cache_ordered;
71const size_t remote_bdaddr_cache_max_size = 1024;
72
73void btif_gattc_add_remote_bdaddr(const RawAddress& p_bda, uint8_t addr_type) {
74  // Remove the oldest entries
75  while (remote_bdaddr_cache.size() >= remote_bdaddr_cache_max_size) {
76    const RawAddress& raw_address = remote_bdaddr_cache_ordered.front();
77    remote_bdaddr_cache.erase(raw_address);
78    remote_bdaddr_cache_ordered.pop();
79  }
80  remote_bdaddr_cache.insert(p_bda);
81  remote_bdaddr_cache_ordered.push(p_bda);
82}
83
84bool btif_gattc_find_bdaddr(const RawAddress& p_bda) {
85  return (remote_bdaddr_cache.find(p_bda) != remote_bdaddr_cache.end());
86}
87
88void btif_gattc_init_dev_cb(void) {
89  remote_bdaddr_cache.clear();
90  remote_bdaddr_cache_ordered = {};
91}
92
93void btif_gatts_upstreams_evt(uint16_t event, char* p_param) {
94  LOG_VERBOSE(LOG_TAG, "%s: Event %d", __func__, event);
95
96  tBTA_GATTC* p_data = (tBTA_GATTC*)p_param;
97  switch (event) {
98    case BTA_GATTC_DEREG_EVT:
99      break;
100
101    case BTA_GATTC_SEARCH_CMPL_EVT: {
102      HAL_CBACK(bt_gatt_callbacks, client->search_complete_cb,
103                p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
104      break;
105    }
106
107    default:
108      LOG_DEBUG(LOG_TAG, "%s: Unhandled event (%d)", __func__, event);
109      break;
110  }
111}
112
113void bta_gatts_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
114  bt_status_t status =
115      btif_transfer_context(btif_gatts_upstreams_evt, (uint16_t)event,
116                            (char*)p_data, sizeof(tBTA_GATTC), NULL);
117  ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
118}
119
120void bta_batch_scan_threshold_cb(tBTM_BLE_REF_VALUE ref_value) {
121  SCAN_CBACK_IN_JNI(batchscan_threshold_cb, ref_value);
122}
123
124void bta_batch_scan_reports_cb(int client_id, tBTA_STATUS status,
125                               uint8_t report_format, uint8_t num_records,
126                               std::vector<uint8_t> data) {
127  SCAN_CBACK_IN_JNI(batchscan_reports_cb, client_id, status, report_format,
128                    num_records, std::move(data));
129}
130
131void bta_scan_results_cb_impl(RawAddress bd_addr, tBT_DEVICE_TYPE device_type,
132                              int8_t rssi, uint8_t addr_type,
133                              uint16_t ble_evt_type, uint8_t ble_primary_phy,
134                              uint8_t ble_secondary_phy,
135                              uint8_t ble_advertising_sid, int8_t ble_tx_power,
136                              uint16_t ble_periodic_adv_int,
137                              vector<uint8_t> value) {
138  uint8_t remote_name_len;
139  bt_device_type_t dev_type;
140  bt_property_t properties;
141
142  const uint8_t* p_eir_remote_name = AdvertiseDataParser::GetFieldByType(
143      value, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
144
145  if (p_eir_remote_name == NULL) {
146    p_eir_remote_name = AdvertiseDataParser::GetFieldByType(
147        value, BT_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
148  }
149
150  if ((addr_type != BLE_ADDR_RANDOM) || (p_eir_remote_name)) {
151    if (!btif_gattc_find_bdaddr(bd_addr)) {
152      btif_gattc_add_remote_bdaddr(bd_addr, addr_type);
153
154      if (p_eir_remote_name) {
155        if (remote_name_len > BD_NAME_LEN + 1 ||
156            (remote_name_len == BD_NAME_LEN + 1 &&
157             p_eir_remote_name[BD_NAME_LEN] != '\0')) {
158          LOG_INFO(LOG_TAG,
159                   "%s dropping invalid packet - device name too long: %d",
160                   __func__, remote_name_len);
161          return;
162        }
163
164        bt_bdname_t bdname;
165        memcpy(bdname.name, p_eir_remote_name, remote_name_len);
166        if (remote_name_len < BD_NAME_LEN + 1)
167          bdname.name[remote_name_len] = '\0';
168
169        LOG_VERBOSE(LOG_TAG, "%s BLE device name=%s len=%d dev_type=%d",
170                    __func__, bdname.name, remote_name_len, device_type);
171        btif_dm_update_ble_remote_properties(bd_addr, bdname.name, device_type);
172      }
173    }
174  }
175
176  dev_type = (bt_device_type_t)device_type;
177  BTIF_STORAGE_FILL_PROPERTY(&properties, BT_PROPERTY_TYPE_OF_DEVICE,
178                             sizeof(dev_type), &dev_type);
179  btif_storage_set_remote_device_property(&(bd_addr), &properties);
180
181  btif_storage_set_remote_addr_type(&bd_addr, addr_type);
182  HAL_CBACK(bt_gatt_callbacks, scanner->scan_result_cb, ble_evt_type, addr_type,
183            &bd_addr, ble_primary_phy, ble_secondary_phy, ble_advertising_sid,
184            ble_tx_power, rssi, ble_periodic_adv_int, std::move(value));
185}
186
187void bta_scan_results_cb(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
188  uint8_t len;
189
190  if (event == BTA_DM_INQ_CMPL_EVT) {
191    BTIF_TRACE_DEBUG("%s  BLE observe complete. Num Resp %d", __func__,
192                     p_data->inq_cmpl.num_resps);
193    return;
194  }
195
196  if (event != BTA_DM_INQ_RES_EVT) {
197    BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event);
198    return;
199  }
200
201  vector<uint8_t> value;
202  if (p_data->inq_res.p_eir) {
203    value.insert(value.begin(), p_data->inq_res.p_eir,
204                 p_data->inq_res.p_eir + p_data->inq_res.eir_len);
205
206    if (AdvertiseDataParser::GetFieldByType(
207            value, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &len)) {
208      p_data->inq_res.remt_name_not_required = true;
209    }
210  }
211
212  tBTA_DM_INQ_RES* r = &p_data->inq_res;
213  do_in_jni_thread(Bind(bta_scan_results_cb_impl, r->bd_addr, r->device_type,
214                        r->rssi, r->ble_addr_type, r->ble_evt_type,
215                        r->ble_primary_phy, r->ble_secondary_phy,
216                        r->ble_advertising_sid, r->ble_tx_power,
217                        r->ble_periodic_adv_int, std::move(value)));
218}
219
220void bta_track_adv_event_cb(tBTM_BLE_TRACK_ADV_DATA* p_track_adv_data) {
221  btgatt_track_adv_info_t* btif_scan_track_cb = new btgatt_track_adv_info_t;
222
223  BTIF_TRACE_DEBUG("%s", __func__);
224  btif_gatt_move_track_adv_data(btif_scan_track_cb,
225                                (btgatt_track_adv_info_t*)p_track_adv_data);
226
227  SCAN_CBACK_IN_JNI(track_adv_event_cb, Owned(btif_scan_track_cb));
228}
229
230class BleScannerInterfaceImpl : public BleScannerInterface {
231  ~BleScannerInterfaceImpl(){};
232
233  void RegisterScanner(RegisterCallback cb) override {
234    do_in_bta_thread(FROM_HERE,
235                     Bind(
236                         [](RegisterCallback cb) {
237                           BTA_GATTC_AppRegister(
238                               bta_gatts_cback,
239                               jni_thread_wrapper(FROM_HERE, std::move(cb)));
240                         },
241                         std::move(cb)));
242  }
243
244  void Unregister(int scanner_id) override {
245    do_in_bta_thread(FROM_HERE, Bind(&BTA_GATTC_AppDeregister, scanner_id));
246  }
247
248  void Scan(bool start) override {
249    do_in_jni_thread(Bind(
250        [](bool start) {
251          if (!start) {
252            do_in_bta_thread(FROM_HERE,
253                             Bind(&BTA_DmBleObserve, false, 0, nullptr));
254            return;
255          }
256
257          btif_gattc_init_dev_cb();
258          do_in_bta_thread(FROM_HERE,
259                           Bind(&BTA_DmBleObserve, true, 0,
260                                (tBTA_DM_SEARCH_CBACK*)bta_scan_results_cb));
261        },
262        start));
263  }
264
265  void ScanFilterParamSetup(
266      uint8_t client_if, uint8_t action, uint8_t filt_index,
267      std::unique_ptr<btgatt_filt_param_setup_t> filt_param,
268      FilterParamSetupCallback cb) override {
269    BTIF_TRACE_DEBUG("%s", __func__);
270
271    if (filt_param && filt_param->dely_mode == 1) {
272      do_in_bta_thread(
273          FROM_HERE, base::Bind(BTM_BleTrackAdvertiser, bta_track_adv_event_cb,
274                                client_if));
275    }
276
277    do_in_bta_thread(FROM_HERE,
278                     base::Bind(&BTM_BleAdvFilterParamSetup, action, filt_index,
279                                base::Passed(&filt_param),
280                                jni_thread_wrapper(FROM_HERE, std::move(cb))));
281  }
282
283  void ScanFilterAddRemove(int action, int filt_type, int filt_index,
284                           int company_id, int company_id_mask,
285                           const bt_uuid_t* p_uuid,
286                           const bt_uuid_t* p_uuid_mask,
287                           const RawAddress* bd_addr, char addr_type,
288                           vector<uint8_t> data, vector<uint8_t> mask,
289                           FilterConfigCallback cb) override {
290    BTIF_TRACE_DEBUG("%s, %d, %d", __func__, action, filt_type);
291
292    /* If data is passed, both mask and data have to be the same length */
293    if (data.size() != mask.size() && data.size() != 0 && mask.size() != 0)
294      return;
295
296    switch (filt_type) {
297      case BTM_BLE_PF_ADDR_FILTER: {
298        tBLE_BD_ADDR target_addr;
299        target_addr.bda = *bd_addr;
300        target_addr.type = addr_type;
301
302        do_in_bta_thread(
303            FROM_HERE,
304            base::Bind(&BTM_LE_PF_addr_filter, action, filt_index,
305                       std::move(target_addr),
306                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
307        return;
308      }
309
310      case BTM_BLE_PF_SRVC_DATA:
311        do_in_bta_thread(FROM_HERE,
312                         base::Bind(&BTM_LE_PF_srvc_data, action, filt_index));
313        return;
314
315      case BTM_BLE_PF_SRVC_UUID:
316      case BTM_BLE_PF_SRVC_SOL_UUID: {
317        tBT_UUID bt_uuid;
318        btif_to_bta_uuid(&bt_uuid, p_uuid);
319
320        if (p_uuid_mask == NULL) {
321          do_in_bta_thread(
322              FROM_HERE,
323              base::Bind(&BTM_LE_PF_uuid_filter, action, filt_index, filt_type,
324                         bt_uuid, BTM_BLE_PF_LOGIC_AND, nullptr,
325                         jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
326          return;
327        }
328
329        tBTM_BLE_PF_COND_MASK* mask = new tBTM_BLE_PF_COND_MASK;
330        btif_to_bta_uuid_mask(mask, p_uuid_mask, p_uuid);
331        do_in_bta_thread(
332            FROM_HERE,
333            base::Bind(&BTM_LE_PF_uuid_filter, action, filt_index, filt_type,
334                       bt_uuid, BTM_BLE_PF_LOGIC_AND, base::Owned(mask),
335                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
336        return;
337      }
338
339      case BTM_BLE_PF_LOCAL_NAME: {
340        do_in_bta_thread(
341            FROM_HERE,
342            base::Bind(&BTM_LE_PF_local_name, action, filt_index,
343                       std::move(data),
344                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
345        return;
346      }
347
348      case BTM_BLE_PF_MANU_DATA: {
349        do_in_bta_thread(
350            FROM_HERE,
351            base::Bind(&BTM_LE_PF_manu_data, action, filt_index, company_id,
352                       company_id_mask, std::move(data), std::move(mask),
353                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
354        return;
355      }
356
357      case BTM_BLE_PF_SRVC_DATA_PATTERN: {
358        do_in_bta_thread(
359            FROM_HERE,
360            base::Bind(&BTM_LE_PF_srvc_data_pattern, action, filt_index,
361                       std::move(data), std::move(mask),
362                       jni_thread_wrapper(FROM_HERE, Bind(cb, filt_type))));
363        return;
364      }
365
366      default:
367        LOG_ERROR(LOG_TAG, "%s: Unknown filter type (%d)!", __func__, action);
368        return;
369    }
370  }
371
372  void ScanFilterClear(int filter_index, FilterConfigCallback cb) override {
373    BTIF_TRACE_DEBUG("%s: filter_index: %d", __func__, filter_index);
374    do_in_bta_thread(FROM_HERE,
375                     base::Bind(&BTM_LE_PF_clear, filter_index,
376                                jni_thread_wrapper(
377                                    FROM_HERE, Bind(cb, BTM_BLE_PF_TYPE_ALL))));
378  }
379
380  void ScanFilterEnable(bool enable, EnableCallback cb) override {
381    BTIF_TRACE_DEBUG("%s: enable: %d", __func__, enable);
382
383    uint8_t action = enable ? 1 : 0;
384    do_in_bta_thread(FROM_HERE,
385                     base::Bind(&BTM_BleEnableDisableFilterFeature, action,
386                                jni_thread_wrapper(FROM_HERE, std::move(cb))));
387  }
388
389  void SetScanParameters(int scan_interval, int scan_window,
390                         Callback cb) override {
391    do_in_bta_thread(
392        FROM_HERE, base::Bind(&BTM_BleSetScanParams, scan_interval, scan_window,
393                              BTM_BLE_SCAN_MODE_ACTI,
394                              jni_thread_wrapper(FROM_HERE, std::move(cb))));
395  }
396
397  void BatchscanConfigStorage(int client_if, int batch_scan_full_max,
398                              int batch_scan_trunc_max,
399                              int batch_scan_notify_threshold,
400                              Callback cb) override {
401    do_in_bta_thread(
402        FROM_HERE,
403        base::Bind(&BTM_BleSetStorageConfig, (uint8_t)batch_scan_full_max,
404                   (uint8_t)batch_scan_trunc_max,
405                   (uint8_t)batch_scan_notify_threshold,
406                   jni_thread_wrapper(FROM_HERE, cb),
407                   bta_batch_scan_threshold_cb, (tBTM_BLE_REF_VALUE)client_if));
408  }
409
410  void BatchscanEnable(int scan_mode, int scan_interval, int scan_window,
411                       int addr_type, int discard_rule, Callback cb) override {
412    do_in_bta_thread(
413        FROM_HERE, base::Bind(&BTM_BleEnableBatchScan, scan_mode, scan_interval,
414                              scan_window, discard_rule, addr_type,
415                              jni_thread_wrapper(FROM_HERE, cb)));
416  }
417
418  void BatchscanDisable(Callback cb) override {
419    do_in_bta_thread(FROM_HERE, base::Bind(&BTM_BleDisableBatchScan,
420                                           jni_thread_wrapper(FROM_HERE, cb)));
421  }
422
423  void BatchscanReadReports(int client_if, int scan_mode) override {
424    do_in_bta_thread(FROM_HERE,
425                     base::Bind(&BTM_BleReadScanReports, (uint8_t)scan_mode,
426                                Bind(bta_batch_scan_reports_cb, client_if)));
427  }
428
429  void StartSync(uint8_t sid, RawAddress address, uint16_t skip,
430                 uint16_t timeout, StartSyncCb start_cb, SyncReportCb report_cb,
431                 SyncLostCb lost_cb) override {}
432
433  void StopSync(uint16_t handle) override {}
434};
435
436BleScannerInterface* btLeScannerInstance = nullptr;
437
438}  // namespace
439
440BleScannerInterface* get_ble_scanner_instance() {
441  if (btLeScannerInstance == nullptr)
442    btLeScannerInstance = new BleScannerInterfaceImpl();
443
444  return btLeScannerInstance;
445}
446