Separate LE scanner from GATT client (4/4)
Right now, LE scanning functionality is combined with the GATT client.
This is the source of various bugs, like scans suddenly stoppinging when
a GATT client is killed. It also increases memory consumption, because
we associate many structures with a GATT client, which are not necessary
when just scanning.
Test: sl4a BleScanApiTest ConcurrentBleScanTest
Bug: 30622771
Change-Id: I23b71255c459b185257654f68ea251b41ed2a14b
diff --git a/btif/src/btif_gatt_client.cc b/btif/src/btif_gatt_client.cc
index cd20ce5..a83fc09 100644
--- a/btif/src/btif_gatt_client.cc
+++ b/btif/src/btif_gatt_client.cc
@@ -297,6 +297,40 @@
ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
}
+void btif_gatts_upstreams_evt(uint16_t event, char* p_param) {
+ LOG_VERBOSE(LOG_TAG, "%s: Event %d", __func__, event);
+
+ tBTA_GATTC* p_data = (tBTA_GATTC*)p_param;
+ switch (event) {
+ case BTA_GATTC_REG_EVT: {
+ bt_uuid_t app_uuid;
+ bta_to_btif_uuid(&app_uuid, &p_data->reg_oper.app_uuid);
+ HAL_CBACK(bt_gatt_callbacks, client->register_scanner_cb,
+ p_data->reg_oper.status, p_data->reg_oper.client_if, &app_uuid);
+ break;
+ }
+
+ case BTA_GATTC_DEREG_EVT:
+ break;
+
+ case BTA_GATTC_SEARCH_CMPL_EVT: {
+ HAL_CBACK(bt_gatt_callbacks, client->search_complete_cb,
+ p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
+ break;
+ }
+
+ default:
+ LOG_ERROR(LOG_TAG, "%s: Unhandled event (%d)!", __func__, event);
+ break;
+ }
+}
+
+void bta_gatts_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
+ bt_status_t status =
+ btif_transfer_context(btif_gatts_upstreams_evt, (uint16_t)event,
+ (char*)p_data, sizeof(tBTA_GATTC), NULL);
+ ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
+}
void bta_batch_scan_setup_cb(tBTA_BLE_BATCH_SCAN_EVT evt,
tBTA_DM_BLE_REF_VALUE ref_value,
tBTA_STATUS status) {
@@ -504,6 +538,29 @@
return do_in_jni_thread(Bind(&btif_gattc_unregister_app_impl, client_if));
}
+
+void btif_gattc_register_scanner_impl(tBT_UUID uuid) {
+ BTA_GATTC_AppRegister(&uuid, bta_gatts_cback);
+}
+
+bt_status_t btif_gattc_register_scanner(bt_uuid_t* uuid) {
+ CHECK_BTGATT_INIT();
+
+ tBT_UUID bt_uuid;
+ btif_to_bta_uuid(&bt_uuid, uuid);
+ return do_in_jni_thread(Bind(&btif_gattc_register_scanner_impl, bt_uuid));
+}
+
+void btif_gattc_unregister_scanner_impl(int client_if) {
+ BTA_GATTC_AppDeregister(client_if);
+}
+
+bt_status_t btif_gattc_unregister_scanner(int scanner_id) {
+ CHECK_BTGATT_INIT();
+ return do_in_jni_thread(Bind(&btif_gattc_unregister_scanner_impl, scanner_id));
+}
+
+
bt_status_t btif_gattc_scan(bool start) {
CHECK_BTGATT_INIT();
if (start) {
@@ -1073,6 +1130,8 @@
const btgatt_client_interface_t btgattClientInterface = {
btif_gattc_register_app,
btif_gattc_unregister_app,
+ btif_gattc_register_scanner,
+ btif_gattc_unregister_scanner,
btif_gattc_scan,
btif_gattc_open,
btif_gattc_close,
diff --git a/service/gatt_server_old.cc b/service/gatt_server_old.cc
index 7eb5b06..9622a00 100644
--- a/service/gatt_server_old.cc
+++ b/service/gatt_server_old.cc
@@ -351,6 +351,11 @@
}
}
+void RegisterScannerCallback(int status, int scanner_id, bt_uuid_t *app_uuid) {
+ LOG_INFO(LOG_TAG, "%s: status:%d scanner_id:%d uuid[0]:%u", __func__, status,
+ scanner_id, app_uuid->uu[0]);
+}
+
void ListenCallback(int status, int client_if) {
LOG_INFO(LOG_TAG, "%s: status:%d client_if:%d", __func__, status, client_if);
// This terminates a Start call.
@@ -419,6 +424,7 @@
// to refer to the client interface.
const btgatt_client_callbacks_t gatt_client_callbacks = {
RegisterClientCallback,
+ RegisterScannerCallback,
ScanResultCallback,
ClientConnectCallback,
ClientDisconnectCallback,
diff --git a/service/hal/bluetooth_gatt_interface.cc b/service/hal/bluetooth_gatt_interface.cc
index 677b6fa..dfc85b5 100644
--- a/service/hal/bluetooth_gatt_interface.cc
+++ b/service/hal/bluetooth_gatt_interface.cc
@@ -80,6 +80,16 @@
RegisterClientCallback(g_interface, status, client_if, *app_uuid));
}
+void RegisterScannerCallback(int status, int scanner_id, bt_uuid_t* app_uuid) {
+ shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ VLOG(2) << __func__ << " - status: " << status << " scanner_id: " << scanner_id;
+ VERIFY_INTERFACE_OR_RETURN();
+ CHECK(app_uuid);
+
+ FOR_EACH_CLIENT_OBSERVER(
+ RegisterScannerCallback(g_interface, status, scanner_id, *app_uuid));
+}
+
void ScanResultCallback(bt_bdaddr_t* bda, int rssi, vector<uint8_t> adv_data) { // NOLINT(pass-by-value)
shared_lock<shared_timed_mutex> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
@@ -387,6 +397,7 @@
// GATT client-role and GAP events.
const btgatt_client_callbacks_t gatt_client_callbacks = {
RegisterClientCallback,
+ RegisterScannerCallback,
ScanResultCallback,
ConnectCallback,
DisconnectCallback,
@@ -555,6 +566,15 @@
const bt_uuid_t& /* app_uuid */) {
// Do nothing.
}
+
+void BluetoothGattInterface::ClientObserver::RegisterScannerCallback(
+ BluetoothGattInterface* /* gatt_iface */,
+ int /* status */,
+ int /* scanner_id */,
+ const bt_uuid_t& /* app_uuid */) {
+ // Do nothing.
+}
+
void BluetoothGattInterface::ClientObserver::ScanResultCallback(
BluetoothGattInterface* /* gatt_iface */,
const bt_bdaddr_t& /* bda */,
diff --git a/service/hal/bluetooth_gatt_interface.h b/service/hal/bluetooth_gatt_interface.h
index 8d43eff..5a0e989 100644
--- a/service/hal/bluetooth_gatt_interface.h
+++ b/service/hal/bluetooth_gatt_interface.h
@@ -57,6 +57,11 @@
int status, int client_if,
const bt_uuid_t& app_uuid);
+ virtual void RegisterScannerCallback(
+ BluetoothGattInterface* gatt_iface,
+ int status, int scanner_id,
+ const bt_uuid_t& app_uuid);
+
virtual void ScanResultCallback(
BluetoothGattInterface* gatt_iface,
const bt_bdaddr_t& bda, int rssi,
diff --git a/service/hal/fake_bluetooth_gatt_interface.cc b/service/hal/fake_bluetooth_gatt_interface.cc
index 4a772b7..b19a216 100644
--- a/service/hal/fake_bluetooth_gatt_interface.cc
+++ b/service/hal/fake_bluetooth_gatt_interface.cc
@@ -41,6 +41,20 @@
return BT_STATUS_FAIL;
}
+bt_status_t FakeRegisterScanner(bt_uuid_t* app_uuid) {
+ if (g_client_handler)
+ return g_client_handler->RegisterClient(app_uuid);
+
+ return BT_STATUS_FAIL;
+}
+
+bt_status_t FakeUnregisterScanner(int client_if) {
+ if (g_client_handler)
+ return g_client_handler->UnregisterClient(client_if);
+
+ return BT_STATUS_FAIL;
+}
+
bt_status_t FakeScan(bool start) {
if (g_client_handler)
return g_client_handler->Scan(start);
@@ -114,6 +128,8 @@
btgatt_client_interface_t fake_btgattc_iface = {
FakeRegisterClient,
FakeUnregisterClient,
+ FakeRegisterScanner,
+ FakeUnregisterScanner,
FakeScan,
FakeConnect,
FakeDisconnect,