summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Rahul Arya <aryarahul@google.com> 2023-01-18 02:35:27 +0000
committer Rahul Arya <aryarahul@google.com> 2023-01-18 02:35:27 +0000
commit2a6137f7374d47b3a9307516af2c0107f5dca887 (patch)
tree386b733546e96cdd1595df26aaa09e27f8bf34e7
parent9aeb48bb7c6ea41e3017b70a42a22c29b0f4a8a9 (diff)
[Offload] Alternative API for getAclHandle()
This is a synchronous API on BluetoothDevice rather than a callback-based one on BluetoothGatt. Test: compiles Bug: 261093955 Change-Id: I3e008e84e1b2e19158984ecee963b9a63e74b8b1
-rw-r--r--android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp10
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterService.java36
-rw-r--r--android/app/src/com/android/bluetooth/btservice/JniCallbacks.java4
-rw-r--r--android/app/src/com/android/bluetooth/btservice/RemoteDevices.java41
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java3
-rw-r--r--framework/api/system-current.txt1
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java36
-rw-r--r--system/binder/android/bluetooth/IBluetooth.aidl2
-rw-r--r--system/bta/dm/bta_dm_act.cc10
-rw-r--r--system/bta/dm/bta_dm_int.h3
-rw-r--r--system/bta/include/bta_api.h1
-rw-r--r--system/bta/include/bta_dm_acl.h3
-rw-r--r--system/btif/include/btif_common.h3
-rw-r--r--system/btif/include/core_callbacks.h3
-rw-r--r--system/btif/src/bluetooth.cc11
-rw-r--r--system/btif/src/btif_dm.cc8
-rw-r--r--system/btif/test/btif_core_test.cc3
-rw-r--r--system/gd/rust/linux/stack/src/bluetooth.rs2
-rw-r--r--system/gd/rust/topshim/src/btif.rs12
-rw-r--r--system/include/hardware/bluetooth.h12
-rw-r--r--system/main/shim/l2c_api.cc2
-rw-r--r--system/service/adapter.cc3
-rw-r--r--system/service/hal/bluetooth_interface.cc12
-rw-r--r--system/service/hal/bluetooth_interface.h3
-rw-r--r--system/service/hal/fake_bluetooth_interface.cc6
-rw-r--r--system/service/hal/fake_bluetooth_interface.h10
-rw-r--r--system/service/test/adapter_unittest.cc6
-rw-r--r--system/stack/acl/btm_acl.cc2
-rw-r--r--system/test/headless/headless.cc4
-rw-r--r--system/test/headless/interface.h10
-rw-r--r--system/test/mock/mock_bluetooth_interface.cc3
-rw-r--r--system/test/mock/mock_bta_dm_act.cc10
-rw-r--r--system/test/mock/mock_bta_dm_act.h22
33 files changed, 226 insertions, 71 deletions
diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
index c67ea1b5dd..c1ac9a5727 100644
--- a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -367,7 +367,8 @@ static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
bt_acl_state_t state,
int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction) {
+ bt_conn_direction_t direction,
+ uint16_t acl_handle) {
if (!bd_addr) {
ALOGE("Address is null in %s", __func__);
return;
@@ -387,7 +388,8 @@ static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr,
sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_aclStateChangeCallback,
(jint)status, addr.get(), (jint)state,
- (jint)transport_link_type, (jint)hci_reason);
+ (jint)transport_link_type, (jint)hci_reason,
+ (jint)acl_handle);
}
static void discovery_state_changed_callback(bt_discovery_state_t state) {
@@ -959,8 +961,8 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
method_leAddressAssociateCallback = env->GetMethodID(
jniCallbackClass, "leAddressAssociateCallback", "([B[B)V");
- method_aclStateChangeCallback =
- env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BIII)V");
+ method_aclStateChangeCallback = env->GetMethodID(
+ jniCallbackClass, "aclStateChangeCallback", "(I[BIIII)V");
method_linkQualityReportCallback = env->GetMethodID(
jniCallbackClass, "linkQualityReportCallback", "(JIIIIII)V");
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
index ec9c9c8f91..03604a957f 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
@@ -2467,6 +2467,34 @@ public class AdapterService extends Service {
}
@Override
+ public void getConnectionHandle(BluetoothDevice device, int transport,
+ AttributionSource source, SynchronousResultReceiver receiver) {
+ try {
+ receiver.send(getConnectionHandle(device, transport, source));
+ } catch (RuntimeException e) {
+ receiver.propagateException(e);
+ }
+ }
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ private int getConnectionHandle(
+ BluetoothDevice device, int transport, AttributionSource attributionSource) {
+ AdapterService service = getService();
+ if (service == null
+ || !callerIsSystemOrActiveOrManagedUser(service, TAG, "setActiveDevice")
+ || !Utils.checkConnectPermissionForDataDelivery(
+ service, attributionSource, TAG)) {
+ return BluetoothDevice.ERROR;
+ }
+
+ enforceBluetoothPrivilegedPermission(service);
+
+ return service.getConnectionHandle(device, transport);
+ }
+
+ @Override
public void canBondWithoutDialog(BluetoothDevice device, AttributionSource source,
SynchronousResultReceiver receiver) {
try {
@@ -4453,6 +4481,14 @@ public class AdapterService extends Service {
return getConnectionStateNative(getBytesFromAddress(device.getAddress()));
}
+ int getConnectionHandle(BluetoothDevice device, int transport) {
+ DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
+ if (deviceProp == null) {
+ return BluetoothDevice.ERROR;
+ }
+ return deviceProp.getConnectionHandle(transport);
+ }
+
/**
* Checks whether the device was recently associated with the comapnion app that called
* {@link BluetoothDevice#createBond}. This allows these devices to skip the pairing dialog if
diff --git a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
index a5c986942a..f7108f494b 100644
--- a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
+++ b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
@@ -76,9 +76,9 @@ final class JniCallbacks {
}
void aclStateChangeCallback(int status, byte[] address, int newState,
- int transportLinkType, int hciReason) {
+ int transportLinkType, int hciReason, int handle) {
mRemoteDevices.aclStateChangeCallback(status, address, newState,
- transportLinkType, hciReason);
+ transportLinkType, hciReason, handle);
}
void stateChangeCallback(int status) {
diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
index 7176fed044..4dd5c6e782 100644
--- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -307,6 +307,8 @@ final class RemoteDevices {
private String mIdentityAddress;
private boolean mIsConsolidated = false;
private int mBluetoothClass = BluetoothClass.Device.Major.UNCATEGORIZED;
+ private int mBredrConnectionHandle = BluetoothDevice.ERROR;
+ private int mLeConnectionHandle = BluetoothDevice.ERROR;
private short mRssi;
private String mAlias;
private BluetoothDevice mDevice;
@@ -395,6 +397,38 @@ final class RemoteDevices {
}
/**
+ * @param transport the transport on which the connection exists
+ * @return the mConnectionHandle
+ */
+ int getConnectionHandle(int transport) {
+ synchronized (mObject) {
+ if (transport == BluetoothDevice.TRANSPORT_BREDR) {
+ return mBredrConnectionHandle;
+ } else if (transport == BluetoothDevice.TRANSPORT_LE) {
+ return mLeConnectionHandle;
+ } else {
+ return BluetoothDevice.ERROR;
+ }
+ }
+ }
+
+ /**
+ * @param connectionHandle the connectionHandle to set
+ * @param transport the transport on which to set the handle
+ */
+ void setConnectionHandle(int connectionHandle, int transport) {
+ synchronized (mObject) {
+ if (transport == BluetoothDevice.TRANSPORT_BREDR) {
+ mBredrConnectionHandle = connectionHandle;
+ } else if (transport == BluetoothDevice.TRANSPORT_LE) {
+ mLeConnectionHandle = connectionHandle;
+ } else {
+ errorLog("setConnectionHandle() unexpected transport value " + transport);
+ }
+ }
+ }
+
+ /**
* @return the mUuids
*/
ParcelUuid[] getUuids() {
@@ -945,7 +979,7 @@ final class RemoteDevices {
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
void aclStateChangeCallback(int status, byte[] address, int newState,
- int transportLinkType, int hciReason) {
+ int transportLinkType, int hciReason, int handle) {
if (status != AbstractionLayer.BT_STATUS_SUCCESS) {
debugLog("aclStateChangeCallback status is " + status + ", skipping");
return;
@@ -958,10 +992,14 @@ final class RemoteDevices {
+ Utils.getAddressStringFromByte(address) + ", newState=" + newState);
return;
}
+
+ DeviceProperties deviceProperties = getDeviceProperties(device);
+
int state = mAdapterService.getState();
Intent intent = null;
if (newState == AbstractionLayer.BT_ACL_STATE_CONNECTED) {
+ deviceProperties.setConnectionHandle(handle, transportLinkType);
if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_TURNING_ON) {
intent = new Intent(BluetoothDevice.ACTION_ACL_CONNECTED);
intent.putExtra(BluetoothDevice.EXTRA_TRANSPORT, transportLinkType);
@@ -979,6 +1017,7 @@ final class RemoteDevices {
"aclStateChangeCallback: Adapter State: " + BluetoothAdapter.nameForState(state)
+ " Connected: " + device);
} else {
+ deviceProperties.setConnectionHandle(BluetoothDevice.ERROR, transportLinkType);
if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
// Send PAIRING_CANCEL intent to dismiss any dialog requesting bonding.
intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java
index b7ba057d24..54a2930f94 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java
@@ -296,7 +296,8 @@ public class RemoteDevicesTest {
// BluetoothDevice.BATTERY_LEVEL_UNKNOWN
when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON);
mRemoteDevices.aclStateChangeCallback(0, Utils.getByteAddress(mDevice1),
- AbstractionLayer.BT_ACL_STATE_DISCONNECTED, 2, 19); // HCI code 19 remote terminated
+ AbstractionLayer.BT_ACL_STATE_DISCONNECTED, 2, 19,
+ BluetoothDevice.ERROR); // HCI code 19 remote terminated
// Verify ACTION_ACL_DISCONNECTED and BATTERY_LEVEL_CHANGED intent are sent
verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(),
mStringArgument.capture(), any(Bundle.class));
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 67db13f4d0..82c9095fe2 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -172,6 +172,7 @@ package android.bluetooth {
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothAudioPolicy getAudioPolicy();
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getAudioPolicyRemoteSupported();
method @IntRange(from=0xffffff9c, to=100) @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getBatteryLevel();
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionHandle(int);
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public String getIdentityAddress();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getMessageAccessPermission();
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public byte[] getMetadata(int);
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index 8d88f26c52..913d310246 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -2207,6 +2207,42 @@ public final class BluetoothDevice implements Parcelable, Attributable {
}
/**
+ * Returns the ACL connection handle associated with an open connection to
+ * this device on the given transport.
+ *
+ * @return the ACL handle, or {@link BluetoothDevice#ERROR} if no connection currently exists on
+ * the given transport.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public int getConnectionHandle(@Transport int transport) {
+ if (DBG) {
+ log("getConnectionHandle()");
+ }
+ final IBluetooth service = getService();
+ if (service == null || !isBluetoothEnabled()) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) {
+ log(Log.getStackTraceString(new Throwable()));
+ }
+ } else {
+ try {
+ final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get();
+ service.getConnectionHandle(this, transport, mAttributionSource, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(-1);
+ } catch (RemoteException | TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ // BT is not enabled, we cannot be connected.
+ return BluetoothDevice.ERROR;
+ }
+
+ /**
* Returns whether there is an open connection to this device
* that has been encrypted.
*
diff --git a/system/binder/android/bluetooth/IBluetooth.aidl b/system/binder/android/bluetooth/IBluetooth.aidl
index 5a7de73223..d14b7053f0 100644
--- a/system/binder/android/bluetooth/IBluetooth.aidl
+++ b/system/binder/android/bluetooth/IBluetooth.aidl
@@ -120,6 +120,8 @@ interface IBluetooth
oneway void getSupportedProfiles(in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
oneway void getConnectionState(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
+ oneway void getConnectionHandle(in BluetoothDevice device, int transport, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
oneway void getRemoteName(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index 1352336adc..302935377c 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -2525,7 +2525,8 @@ static tBTA_DM_PEER_DEVICE* allocate_device_for(const RawAddress& bd_addr,
return nullptr;
}
-void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
+void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle) {
auto device = allocate_device_for(bd_addr, transport);
if (device == nullptr) {
LOG_WARN("Unable to allocate device resources for new connection");
@@ -2552,6 +2553,7 @@ void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
memset(&conn, 0, sizeof(tBTA_DM_SEC));
conn.link_up.bd_addr = bd_addr;
conn.link_up.transport_link_type = transport;
+ conn.link_up.acl_handle = acl_handle;
bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, &conn);
LOG_DEBUG("Executed security callback for new connection available");
@@ -2559,8 +2561,10 @@ void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
bta_dm_adjust_roles(true);
}
-void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport) {
- do_in_main_thread(FROM_HERE, base::Bind(bta_dm_acl_up, bd_addr, transport));
+void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle) {
+ do_in_main_thread(FROM_HERE,
+ base::Bind(bta_dm_acl_up, bd_addr, transport, acl_handle));
}
static void bta_dm_acl_up_failed(const RawAddress bd_addr,
diff --git a/system/bta/dm/bta_dm_int.h b/system/bta/dm/bta_dm_int.h
index 1109a50cc4..8bd58c3697 100644
--- a/system/bta/dm/bta_dm_int.h
+++ b/system/bta/dm/bta_dm_int.h
@@ -242,7 +242,8 @@ struct tBTA_DM_PEER_DEVICE {
bool in_use;
private:
- friend void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport);
+ friend void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle);
friend void bta_dm_pm_btm_status(const RawAddress& bd_addr,
tBTM_PM_STATUS status, uint16_t value,
tHCI_STATUS hci_status);
diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h
index ff85ece8a9..4331919f9e 100644
--- a/system/bta/include/bta_api.h
+++ b/system/bta/include/bta_api.h
@@ -336,6 +336,7 @@ typedef struct {
typedef struct {
RawAddress bd_addr; /* BD address peer device. */
tBT_TRANSPORT transport_link_type;
+ uint16_t acl_handle;
} tBTA_DM_LINK_UP;
/* Structure associated with BTA_DM_LINK_UP_FAILED_EVT */
diff --git a/system/bta/include/bta_dm_acl.h b/system/bta/include/bta_dm_acl.h
index a49d8ee826..ec72485145 100644
--- a/system/bta/include/bta_dm_acl.h
+++ b/system/bta/include/bta_dm_acl.h
@@ -24,7 +24,8 @@
#include "types/hci_role.h"
#include "types/raw_address.h"
-void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport);
+void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle);
void BTA_dm_acl_up_failed(const RawAddress bd_addr, tBT_TRANSPORT transport,
tHCI_STATUS hci_status);
void BTA_dm_acl_down(const RawAddress bd_addr, tBT_TRANSPORT transport);
diff --git a/system/btif/include/btif_common.h b/system/btif/include/btif_common.h
index 4d69014a9f..72d2117a6f 100644
--- a/system/btif/include/btif_common.h
+++ b/system/btif/include/btif_common.h
@@ -225,7 +225,8 @@ void invoke_le_address_associate_cb(RawAddress main_bd_addr,
void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr,
bt_acl_state_t state, int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction);
+ bt_conn_direction_t direction,
+ uint16_t acl_handle);
void invoke_thread_evt_cb(bt_cb_thread_evt event);
void invoke_le_test_mode_cb(bt_status_t status, uint16_t count);
void invoke_energy_info_cb(bt_activity_energy_info energy_info,
diff --git a/system/btif/include/core_callbacks.h b/system/btif/include/core_callbacks.h
index 12a1ac6271..16e5856bf4 100644
--- a/system/btif/include/core_callbacks.h
+++ b/system/btif/include/core_callbacks.h
@@ -55,7 +55,8 @@ struct EventCallbacks {
bt_acl_state_t state,
int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction);
+ bt_conn_direction_t direction,
+ uint16_t acl_handle);
void (*invoke_thread_evt_cb)(bt_cb_thread_evt event);
void (*invoke_le_test_mode_cb)(bt_status_t status, uint16_t count);
void (*invoke_energy_info_cb)(bt_activity_energy_info energy_info,
diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc
index b303c3d095..96b8233029 100644
--- a/system/btif/src/bluetooth.cc
+++ b/system/btif/src/bluetooth.cc
@@ -1239,17 +1239,20 @@ void invoke_le_address_associate_cb(RawAddress main_bd_addr,
void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr,
bt_acl_state_t state, int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction) {
+ bt_conn_direction_t direction,
+ uint16_t acl_handle) {
do_in_jni_thread(
FROM_HERE,
base::BindOnce(
[](bt_status_t status, RawAddress bd_addr, bt_acl_state_t state,
int transport_link_type, bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction) {
+ bt_conn_direction_t direction, uint16_t acl_handle) {
HAL_CBACK(bt_hal_cbacks, acl_state_changed_cb, status, &bd_addr,
- state, transport_link_type, hci_reason, direction);
+ state, transport_link_type, hci_reason, direction,
+ acl_handle);
},
- status, bd_addr, state, transport_link_type, hci_reason, direction));
+ status, bd_addr, state, transport_link_type, hci_reason, direction,
+ acl_handle));
}
void invoke_thread_evt_cb(bt_cb_thread_evt event) {
diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc
index 84fdd66faf..e8186ba3a7 100644
--- a/system/btif/src/btif_dm.cc
+++ b/system/btif/src/btif_dm.cc
@@ -1923,7 +1923,8 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) {
(int)p_data->link_up.transport_link_type, HCI_SUCCESS,
btm_is_acl_locally_initiated()
? bt_conn_direction_t::BT_CONN_DIRECTION_OUTGOING
- : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING);
+ : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING,
+ p_data->link_up.acl_handle);
break;
case BTA_DM_LINK_UP_FAILED_EVT:
@@ -1933,7 +1934,8 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) {
p_data->link_up_failed.status,
btm_is_acl_locally_initiated()
? bt_conn_direction_t::BT_CONN_DIRECTION_OUTGOING
- : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING);
+ : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING,
+ INVALID_ACL_HANDLE);
break;
case BTA_DM_LINK_DOWN_EVT: {
@@ -1961,7 +1963,7 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) {
BT_STATUS_SUCCESS, bd_addr, BT_ACL_STATE_DISCONNECTED,
(int)p_data->link_down.transport_link_type,
static_cast<bt_hci_error_code_t>(btm_get_acl_disc_reason_code()),
- direction);
+ direction, INVALID_ACL_HANDLE);
LOG_DEBUG(
"Sent BT_ACL_STATE_DISCONNECTED upward as ACL link down event "
"device:%s reason:%s",
diff --git a/system/btif/test/btif_core_test.cc b/system/btif/test/btif_core_test.cc
index 9a7e6840b0..fae3b8ab95 100644
--- a/system/btif/test/btif_core_test.cc
+++ b/system/btif/test/btif_core_test.cc
@@ -78,7 +78,8 @@ void le_address_associate_callback(RawAddress* main_bd_addr,
void acl_state_changed_callback(bt_status_t status, RawAddress* remote_bd_addr,
bt_acl_state_t state, int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction) {}
+ bt_conn_direction_t direction,
+ uint16_t acl_handle) {}
void link_quality_report_callback(uint64_t timestamp, int report_id, int rssi,
int snr, int retransmission_count,
int packets_not_receive_count,
diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs
index 54346a974a..d0eb60b115 100644
--- a/system/gd/rust/linux/stack/src/bluetooth.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth.rs
@@ -782,6 +782,7 @@ pub(crate) trait BtifBluetoothCallbacks {
link_type: BtTransport,
hci_reason: BtHciErrorCode,
conn_direction: BtConnectionDirection,
+ acl_handle: u16,
) {
}
@@ -1143,6 +1144,7 @@ impl BtifBluetoothCallbacks for Bluetooth {
link_type: BtTransport,
hci_reason: BtHciErrorCode,
conn_direction: BtConnectionDirection,
+ acl_handle: u16,
) {
if status != BtStatus::Success {
warn!(
diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs
index b5f9eab13a..cd2d0f5aeb 100644
--- a/system/gd/rust/topshim/src/btif.rs
+++ b/system/gd/rust/topshim/src/btif.rs
@@ -839,7 +839,15 @@ pub enum BaseCallbacks {
BondState(BtStatus, RawAddress, BtBondState, i32),
AddressConsolidate(RawAddress, RawAddress),
LeAddressAssociate(RawAddress, RawAddress),
- AclState(BtStatus, RawAddress, BtAclState, BtTransport, BtHciErrorCode, BtConnectionDirection),
+ AclState(
+ BtStatus,
+ RawAddress,
+ BtAclState,
+ BtTransport,
+ BtHciErrorCode,
+ BtConnectionDirection,
+ u16,
+ ),
// Unimplemented so far:
// thread_evt_cb
// dut_mode_recv_cb
@@ -902,7 +910,7 @@ cb_variant!(BaseCb, le_address_associate_cb -> BaseCallbacks::LeAddressAssociate
});
cb_variant!(BaseCb, acl_state_cb -> BaseCallbacks::AclState,
-u32 -> BtStatus, *mut RawAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, bindings::bt_conn_direction_t -> BtConnectionDirection, {
+u32 -> BtStatus, *mut RawAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, bindings::bt_conn_direction_t -> BtConnectionDirection, u16 -> u16, {
let _1 = unsafe { *(_1 as *const RawAddress) };
});
diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h
index a5e1193f67..beae42218c 100644
--- a/system/include/hardware/bluetooth.h
+++ b/system/include/hardware/bluetooth.h
@@ -183,6 +183,8 @@ typedef enum {
BT_CONN_DIRECTION_INCOMING
} bt_conn_direction_t;
+constexpr uint16_t INVALID_ACL_HANDLE = 0xFFFF;
+
/** Bluetooth SDP service record */
typedef struct {
bluetooth::Uuid uuid;
@@ -495,12 +497,10 @@ typedef void (*le_address_associate_callback)(RawAddress* main_bd_addr,
RawAddress* secondary_bd_addr);
/** Bluetooth ACL connection state changed callback */
-typedef void (*acl_state_changed_callback)(bt_status_t status,
- RawAddress* remote_bd_addr,
- bt_acl_state_t state,
- int transport_link_type,
- bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction);
+typedef void (*acl_state_changed_callback)(
+ bt_status_t status, RawAddress* remote_bd_addr, bt_acl_state_t state,
+ int transport_link_type, bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction, uint16_t acl_handle);
/** Bluetooth link quality report callback */
typedef void (*link_quality_report_callback)(
diff --git a/system/main/shim/l2c_api.cc b/system/main/shim/l2c_api.cc
index df67c648c9..9783f555a1 100644
--- a/system/main/shim/l2c_api.cc
+++ b/system/main/shim/l2c_api.cc
@@ -482,7 +482,7 @@ class SecurityListenerShim
address_to_handle_[bda] = handle;
btm_sec_connected(bda, handle, HCI_SUCCESS, 0);
BTM_PM_OnConnected(handle, bda);
- BTA_dm_acl_up(bda, BT_TRANSPORT_BR_EDR);
+ BTA_dm_acl_up(bda, BT_TRANSPORT_BR_EDR, handle);
address_to_interface_[bda] = std::move(interface);
}
diff --git a/system/service/adapter.cc b/system/service/adapter.cc
index a89477240e..73cf836025 100644
--- a/system/service/adapter.cc
+++ b/system/service/adapter.cc
@@ -693,7 +693,8 @@ class AdapterImpl : public Adapter, public hal::BluetoothInterface::Observer {
const RawAddress& remote_bdaddr,
bt_acl_state_t state, int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction) override {
+ bt_conn_direction_t direction,
+ uint16_t acl_handle) override {
std::string device_address = BtAddrString(&remote_bdaddr);
bool connected = (state == BT_ACL_STATE_CONNECTED);
LOG(INFO) << "ACL state changed: " << device_address
diff --git a/system/service/hal/bluetooth_interface.cc b/system/service/hal/bluetooth_interface.cc
index 01f2ff5714..40cc2842b0 100644
--- a/system/service/hal/bluetooth_interface.cc
+++ b/system/service/hal/bluetooth_interface.cc
@@ -164,7 +164,8 @@ void LeAddressAssociateCallback(RawAddress* main_bd_addr,
void AclStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr,
bt_acl_state_t state, int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction) {
+ bt_conn_direction_t direction,
+ uint16_t acl_handle) {
shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
CHECK(remote_bd_addr);
@@ -173,9 +174,9 @@ void AclStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr,
<< " - BD_ADDR: " << BtAddrString(remote_bd_addr) << " - state: "
<< ((state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED")
<< " - HCI_REASON: " << std::to_string(hci_reason);
- FOR_EACH_BLUETOOTH_OBSERVER(
- AclStateChangedCallback(status, *remote_bd_addr, state,
- transport_link_type, hci_reason, direction));
+ FOR_EACH_BLUETOOTH_OBSERVER(AclStateChangedCallback(
+ status, *remote_bd_addr, state, transport_link_type, hci_reason,
+ direction, acl_handle));
}
void ThreadEventCallback(bt_cb_thread_evt evt) {
@@ -454,7 +455,8 @@ void BluetoothInterface::Observer::BondStateChangedCallback(
void BluetoothInterface::Observer::AclStateChangedCallback(
bt_status_t /* status */, const RawAddress& /* remote_bdaddr */,
bt_acl_state_t /* state */, int /* transport_link_type */,
- bt_hci_error_code_t /* hci_reason */, bt_conn_direction_t /* direction */) {
+ bt_hci_error_code_t /* hci_reason */, bt_conn_direction_t /* direction */,
+ uint16_t /* acl_handle*/) {
// Do nothing.
}
diff --git a/system/service/hal/bluetooth_interface.h b/system/service/hal/bluetooth_interface.h
index 82f9f9c07a..03b9f20e10 100644
--- a/system/service/hal/bluetooth_interface.h
+++ b/system/service/hal/bluetooth_interface.h
@@ -77,7 +77,8 @@ class BluetoothInterface {
bt_acl_state_t state,
int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction);
+ bt_conn_direction_t direction,
+ uint16_t acl_handle);
virtual void LinkQualityReportCallback(
uint64_t timestamp, int report_id, int rssi, int snr,
int retransmission_count, int packets_not_receive_count,
diff --git a/system/service/hal/fake_bluetooth_interface.cc b/system/service/hal/fake_bluetooth_interface.cc
index c0884f24be..fa81ad2026 100644
--- a/system/service/hal/fake_bluetooth_interface.cc
+++ b/system/service/hal/fake_bluetooth_interface.cc
@@ -159,11 +159,11 @@ void FakeBluetoothInterface::NotifyAdapterLocalLeFeaturesPropertyChanged(
void FakeBluetoothInterface::NotifyAclStateChangedCallback(
bt_status_t status, const RawAddress& remote_bdaddr, bt_acl_state_t state,
int transport_link_type, bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction) {
+ bt_conn_direction_t direction, uint16_t acl_handle) {
for (auto& observer : observers_) {
observer.AclStateChangedCallback(status, remote_bdaddr, state,
- transport_link_type, hci_reason,
- direction);
+ transport_link_type, hci_reason, direction,
+ acl_handle);
}
}
diff --git a/system/service/hal/fake_bluetooth_interface.h b/system/service/hal/fake_bluetooth_interface.h
index 9beabe26ce..28ed335686 100644
--- a/system/service/hal/fake_bluetooth_interface.h
+++ b/system/service/hal/fake_bluetooth_interface.h
@@ -58,12 +58,10 @@ class FakeBluetoothInterface : public BluetoothInterface {
void NotifyAdapterAddressPropertyChanged(const RawAddress* address);
void NotifyAdapterLocalLeFeaturesPropertyChanged(
const bt_local_le_features_t* features);
- void NotifyAclStateChangedCallback(bt_status_t status,
- const RawAddress& remote_bdaddr,
- bt_acl_state_t state,
- int transport_link_type,
- bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction);
+ void NotifyAclStateChangedCallback(
+ bt_status_t status, const RawAddress& remote_bdaddr, bt_acl_state_t state,
+ int transport_link_type, bt_hci_error_code_t hci_reason,
+ bt_conn_direction_t direction, uint16_t acl_handle);
// hal::BluetoothInterface overrides:
void AddObserver(Observer* observer) override;
diff --git a/system/service/test/adapter_unittest.cc b/system/service/test/adapter_unittest.cc
index c88dc2d6e7..fb6a9a2263 100644
--- a/system/service/test/adapter_unittest.cc
+++ b/system/service/test/adapter_unittest.cc
@@ -263,7 +263,7 @@ TEST_F(AdapterTest, IsDeviceConnected) {
// status != BT_STATUS_SUCCESS should be ignored
fake_hal_iface_->NotifyAclStateChangedCallback(
BT_STATUS_FAIL, hal_addr, BT_ACL_STATE_CONNECTED, BT_TRANSPORT_LE, 0xff,
- BT_CONN_DIRECTION_OUTGOING); // HCI_ERR_UNDEFINED
+ BT_CONN_DIRECTION_OUTGOING, 1); // HCI_ERR_UNDEFINED
EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr));
EXPECT_TRUE(observer.last_connection_state_address().empty());
EXPECT_FALSE(observer.last_device_connected_state());
@@ -271,7 +271,7 @@ TEST_F(AdapterTest, IsDeviceConnected) {
// Connected
fake_hal_iface_->NotifyAclStateChangedCallback(
BT_STATUS_SUCCESS, hal_addr, BT_ACL_STATE_CONNECTED, BT_TRANSPORT_LE,
- 0x00, BT_CONN_DIRECTION_OUTGOING); // HCI_SUCCESS
+ 0x00, BT_CONN_DIRECTION_OUTGOING, 1); // HCI_SUCCESS
EXPECT_TRUE(adapter_->IsDeviceConnected(kDeviceAddr));
EXPECT_EQ(kDeviceAddr, observer.last_connection_state_address());
EXPECT_TRUE(observer.last_device_connected_state());
@@ -279,7 +279,7 @@ TEST_F(AdapterTest, IsDeviceConnected) {
// Disconnected
fake_hal_iface_->NotifyAclStateChangedCallback(
BT_STATUS_SUCCESS, hal_addr, BT_ACL_STATE_DISCONNECTED, BT_TRANSPORT_LE,
- 0x16, BT_CONN_DIRECTION_OUTGOING); // HCI_ERR_CONN_CAUSE_LOCAL_HOST
+ 0x16, BT_CONN_DIRECTION_OUTGOING, 1); // HCI_ERR_CONN_CAUSE_LOCAL_HOST
EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr));
EXPECT_EQ(kDeviceAddr, observer.last_connection_state_address());
EXPECT_FALSE(observer.last_device_connected_state());
diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc
index add7c4a4fd..5a2c47859e 100644
--- a/system/stack/acl/btm_acl.cc
+++ b/system/stack/acl/btm_acl.cc
@@ -162,7 +162,7 @@ void NotifyAclLinkUp(tACL_CONN& p_acl) {
return;
}
p_acl.link_up_issued = true;
- BTA_dm_acl_up(p_acl.remote_addr, p_acl.transport);
+ BTA_dm_acl_up(p_acl.remote_addr, p_acl.transport, p_acl.hci_handle);
}
void NotifyAclLinkDown(tACL_CONN& p_acl) {
diff --git a/system/test/headless/headless.cc b/system/test/headless/headless.cc
index 74a89e5799..9006afd139 100644
--- a/system/test/headless/headless.cc
+++ b/system/test/headless/headless.cc
@@ -156,7 +156,7 @@ void le_address_associate([[maybe_unused]] RawAddress* main_bd_addr,
void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
bt_acl_state_t state, int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction) {
+ bt_conn_direction_t direction, uint16_t acl_handle) {
CHECK(remote_bd_addr != nullptr);
const size_t num_callbacks = interface_api_callback_map_.size();
auto callback_list = interface_api_callback_map_.find(__func__);
@@ -165,7 +165,7 @@ void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
for (auto callback : callback_list->second) {
acl_state_changed_params_t params(status, raw_address, state,
transport_link_type, hci_reason,
- direction);
+ direction, acl_handle);
(callback)(&params);
}
}
diff --git a/system/test/headless/interface.h b/system/test/headless/interface.h
index 248285b72a..370d86138e 100644
--- a/system/test/headless/interface.h
+++ b/system/test/headless/interface.h
@@ -39,14 +39,15 @@ struct acl_state_changed_params_t : public callback_params_t {
acl_state_changed_params_t(bt_status_t status, RawAddress remote_bd_addr,
bt_acl_state_t state, int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction)
+ bt_conn_direction_t direction, uint16_t acl_handle)
: callback_params_t("acl_state_changed"),
status(status),
remote_bd_addr(remote_bd_addr),
state(state),
transport_link_type(transport_link_type),
hci_reason(hci_reason),
- direction(direction) {}
+ direction(direction),
+ acl_handle(acl_handle) {}
acl_state_changed_params_t(const acl_state_changed_params_t& params) =
default;
virtual ~acl_state_changed_params_t() {}
@@ -57,17 +58,18 @@ struct acl_state_changed_params_t : public callback_params_t {
int transport_link_type;
bt_hci_error_code_t hci_reason;
bt_conn_direction_t direction;
+ uint16_t acl_handle;
std::string ToString() const override {
return base::StringPrintf(
"status:%s remote_bd_addr:%s state:%s transport:%s reason:%s "
- "direction:%d",
+ "direction:%d handle:%d",
bt_status_text(status).c_str(), remote_bd_addr.ToString().c_str(),
(state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED",
bt_transport_text(static_cast<const tBT_TRANSPORT>(transport_link_type))
.c_str(),
bt_status_text(static_cast<const bt_status_t>(hci_reason)).c_str(),
- direction);
+ direction, acl_handle);
}
};
diff --git a/system/test/mock/mock_bluetooth_interface.cc b/system/test/mock/mock_bluetooth_interface.cc
index 17be0f6e4c..728547f666 100644
--- a/system/test/mock/mock_bluetooth_interface.cc
+++ b/system/test/mock/mock_bluetooth_interface.cc
@@ -269,7 +269,8 @@ void invoke_le_address_associate_cb(RawAddress main_bd_addr,
void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr,
bt_acl_state_t state, int transport_link_type,
bt_hci_error_code_t hci_reason,
- bt_conn_direction_t direction) {}
+ bt_conn_direction_t direction,
+ uint16_t acl_handle) {}
void invoke_thread_evt_cb(bt_cb_thread_evt event) {}
diff --git a/system/test/mock/mock_bta_dm_act.cc b/system/test/mock/mock_bta_dm_act.cc
index b64f5f62fc..5f6e2d7d75 100644
--- a/system/test/mock/mock_bta_dm_act.cc
+++ b/system/test/mock/mock_bta_dm_act.cc
@@ -116,9 +116,10 @@ void BTA_dm_acl_down(const RawAddress bd_addr, tBT_TRANSPORT transport) {
mock_function_count_map[__func__]++;
test::mock::bta_dm_act::BTA_dm_acl_down(bd_addr, transport);
}
-void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport) {
+void BTA_dm_acl_up(const RawAddress bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle) {
mock_function_count_map[__func__]++;
- test::mock::bta_dm_act::BTA_dm_acl_up(bd_addr, transport);
+ test::mock::bta_dm_act::BTA_dm_acl_up(bd_addr, transport, acl_handle);
}
void BTA_dm_acl_up_failed(const RawAddress bd_addr, tBT_TRANSPORT transport,
tHCI_STATUS hci_status) {
@@ -143,9 +144,10 @@ void BTA_dm_report_role_change(const RawAddress bd_addr, tHCI_ROLE new_role,
test::mock::bta_dm_act::BTA_dm_report_role_change(bd_addr, new_role,
hci_status);
}
-void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
+void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle) {
mock_function_count_map[__func__]++;
- test::mock::bta_dm_act::bta_dm_acl_up(bd_addr, transport);
+ test::mock::bta_dm_act::bta_dm_acl_up(bd_addr, transport, acl_handle);
}
void bta_dm_add_ble_device(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
tBT_DEVICE_TYPE dev_type) {
diff --git a/system/test/mock/mock_bta_dm_act.h b/system/test/mock/mock_bta_dm_act.h
index 755e04d181..3f2867a08c 100644
--- a/system/test/mock/mock_bta_dm_act.h
+++ b/system/test/mock/mock_bta_dm_act.h
@@ -91,10 +91,13 @@ extern struct BTA_dm_acl_down BTA_dm_acl_down;
// Params: const RawAddress bd_addr, tBT_TRANSPORT transport
// Return: void
struct BTA_dm_acl_up {
- std::function<void(const RawAddress bd_addr, tBT_TRANSPORT transport)> body{
- [](const RawAddress bd_addr, tBT_TRANSPORT transport) {}};
- void operator()(const RawAddress bd_addr, tBT_TRANSPORT transport) {
- body(bd_addr, transport);
+ std::function<void(const RawAddress bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle)>
+ body{[](const RawAddress bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle) {}};
+ void operator()(const RawAddress bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle) {
+ body(bd_addr, transport, acl_handle);
};
};
extern struct BTA_dm_acl_up BTA_dm_acl_up;
@@ -162,10 +165,13 @@ extern struct BTA_dm_report_role_change BTA_dm_report_role_change;
// Params: const RawAddress& bd_addr, tBT_TRANSPORT transport
// Return: void
struct bta_dm_acl_up {
- std::function<void(const RawAddress& bd_addr, tBT_TRANSPORT transport)> body{
- [](const RawAddress& bd_addr, tBT_TRANSPORT transport) {}};
- void operator()(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
- body(bd_addr, transport);
+ std::function<void(const RawAddress& bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle)>
+ body{[](const RawAddress& bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle) {}};
+ void operator()(const RawAddress& bd_addr, tBT_TRANSPORT transport,
+ uint16_t acl_handle) {
+ body(bd_addr, transport, acl_handle);
};
};
extern struct bta_dm_acl_up bta_dm_acl_up;