[Private GATT] Add API to use a isolated GATT server
Associated / unassociates a server with an advertiser, plumbs
logic into Rust.
Bug: 255880936
Test: CTS
Change-Id: I86a29d0bca54f4f99a2f6fb3c11c5a9384a29f71
diff --git a/android/app/jni/com_android_bluetooth_gatt.cpp b/android/app/jni/com_android_bluetooth_gatt.cpp
index c4d62b7..d061a18 100644
--- a/android/app/jni/com_android_bluetooth_gatt.cpp
+++ b/android/app/jni/com_android_bluetooth_gatt.cpp
@@ -2255,12 +2255,10 @@
false, status);
}
-static void startAdvertisingSetNative(JNIEnv* env, jobject object,
- jobject parameters, jbyteArray adv_data,
- jbyteArray scan_resp,
- jobject periodic_parameters,
- jbyteArray periodic_data, jint duration,
- jint maxExtAdvEvents, jint reg_id) {
+static void startAdvertisingSetNative(
+ JNIEnv* env, jobject object, jobject parameters, jbyteArray adv_data,
+ jbyteArray scan_resp, jobject periodic_parameters, jbyteArray periodic_data,
+ jint duration, jint maxExtAdvEvents, jint reg_id, jint server_if) {
if (!sGattIf) return;
jbyte* scan_resp_data = env->GetByteArrayElements(scan_resp, NULL);
@@ -2284,16 +2282,23 @@
periodic_data_data, periodic_data_data + periodic_data_len);
env->ReleaseByteArrayElements(periodic_data, periodic_data_data, JNI_ABORT);
- sGattIf->advertiser->StartAdvertisingSet(
+ auto advertiser_id = sGattIf->advertiser->StartAdvertisingSet(
reg_id, base::Bind(&ble_advertising_set_started_cb, reg_id), params,
data_vec, scan_resp_vec, periodicParams, periodic_data_vec, duration,
maxExtAdvEvents, base::Bind(ble_advertising_set_timeout_cb));
+
+ // tie advertiser ID to server_if
+ if (server_if != 0) {
+ bluetooth::gatt::associate_server_with_advertiser(server_if, advertiser_id);
+ }
}
static void stopAdvertisingSetNative(JNIEnv* env, jobject object,
jint advertiser_id) {
if (!sGattIf) return;
+ bluetooth::gatt::clear_advertiser(advertiser_id);
+
sGattIf->advertiser->Unregister(advertiser_id);
}
@@ -2525,7 +2530,7 @@
{"cleanupNative", "()V", (void*)advertiseCleanupNative},
{"startAdvertisingSetNative",
"(Landroid/bluetooth/le/AdvertisingSetParameters;[B[BLandroid/bluetooth/"
- "le/PeriodicAdvertisingParameters;[BIII)V",
+ "le/PeriodicAdvertisingParameters;[BIIII)V",
(void*)startAdvertisingSetNative},
{"getOwnAddressNative", "(I)V", (void*)getOwnAddressNative},
{"stopAdvertisingSetNative", "(I)V", (void*)stopAdvertisingSetNative},
diff --git a/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java b/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java
index f1c83b3..6f52e74 100644
--- a/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java
+++ b/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java
@@ -206,7 +206,7 @@
void startAdvertisingSet(AdvertisingSetParameters parameters, AdvertiseData advertiseData,
AdvertiseData scanResponse, PeriodicAdvertisingParameters periodicParameters,
- AdvertiseData periodicData, int duration, int maxExtAdvEvents,
+ AdvertiseData periodicData, int duration, int maxExtAdvEvents, int serverIf,
IAdvertisingSetCallback callback) {
AdvertisingSetDeathRecipient deathRecipient = new AdvertisingSetDeathRecipient(callback);
IBinder binder = toBinder(callback);
@@ -236,7 +236,8 @@
scanResponse, periodicParameters, periodicData, duration, maxExtAdvEvents);
startAdvertisingSetNative(parameters, advDataBytes, scanResponseBytes,
- periodicParameters, periodicDataBytes, duration, maxExtAdvEvents, cbId);
+ periodicParameters, periodicDataBytes, duration, maxExtAdvEvents, cbId,
+ serverIf);
} catch (IllegalArgumentException e) {
try {
@@ -534,7 +535,7 @@
private native void startAdvertisingSetNative(AdvertisingSetParameters parameters,
byte[] advertiseData, byte[] scanResponse,
PeriodicAdvertisingParameters periodicParameters, byte[] periodicData, int duration,
- int maxExtAdvEvents, int regId);
+ int maxExtAdvEvents, int regId, int serverIf);
private native void getOwnAddressNative(int advertiserId);
diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java
index 7feb07f..75abb9b 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattService.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattService.java
@@ -24,7 +24,6 @@
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.app.Service;
-import android.content.Context;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
@@ -54,8 +53,9 @@
import android.companion.CompanionDeviceManager;
import android.content.AttributionSource;
import android.content.Intent;
-import android.content.pm.PackageManager.PackageInfoFlags;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManager.PackageInfoFlags;
+import android.content.res.Resources;
import android.net.MacAddress;
import android.os.Binder;
import android.os.Build;
@@ -102,8 +102,6 @@
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
-import android.content.res.Resources;
-
/**
* Provides Bluetooth Gatt profile, as a service in
* the Bluetooth application.
@@ -1441,11 +1439,12 @@
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters, AdvertiseData periodicData,
- int duration, int maxExtAdvEvents, IAdvertisingSetCallback callback,
+ int duration, int maxExtAdvEvents, int serverIf, IAdvertisingSetCallback callback,
AttributionSource attributionSource, SynchronousResultReceiver receiver) {
try {
startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, duration, maxExtAdvEvents, callback, attributionSource);
+ periodicData, duration, maxExtAdvEvents, serverIf, callback,
+ attributionSource);
receiver.send(null);
} catch (RuntimeException e) {
receiver.propagateException(e);
@@ -1454,14 +1453,14 @@
private void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters, AdvertiseData periodicData,
- int duration, int maxExtAdvEvents, IAdvertisingSetCallback callback,
+ int duration, int maxExtAdvEvents, int serverIf, IAdvertisingSetCallback callback,
AttributionSource attributionSource) {
GattService service = getService();
if (service == null) {
return;
}
service.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, duration, maxExtAdvEvents, callback, attributionSource);
+ periodicData, duration, maxExtAdvEvents, serverIf, callback, attributionSource);
}
@Override
@@ -3383,17 +3382,18 @@
@RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
void startAdvertisingSet(AdvertisingSetParameters parameters, AdvertiseData advertiseData,
AdvertiseData scanResponse, PeriodicAdvertisingParameters periodicParameters,
- AdvertiseData periodicData, int duration, int maxExtAdvEvents,
+ AdvertiseData periodicData, int duration, int maxExtAdvEvents, int serverIf,
IAdvertisingSetCallback callback, AttributionSource attributionSource) {
if (!Utils.checkAdvertisePermissionForDataDelivery(
this, attributionSource, "GattService startAdvertisingSet")) {
return;
}
- if (parameters.getOwnAddressType() != AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT) {
+ if (parameters.getOwnAddressType() != AdvertisingSetParameters.ADDRESS_TYPE_DEFAULT
+ || serverIf != 0) {
Utils.enforceBluetoothPrivilegedPermission(this);
}
mAdvertiseManager.startAdvertisingSet(parameters, advertiseData, scanResponse,
- periodicParameters, periodicData, duration, maxExtAdvEvents, callback);
+ periodicParameters, periodicData, duration, maxExtAdvEvents, serverIf, callback);
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java
index eca9508..74d0e64 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java
@@ -88,7 +88,7 @@
doNothing().when(mBinder).linkToDeath(any(), eq(0));
mAdvertiseManager.startAdvertisingSet(parameters, advertiseData, scanResponse,
- periodicParameters, periodicData, duration, maxExtAdvEvents, mCallback);
+ periodicParameters, periodicData, duration, maxExtAdvEvents, 0, mCallback);
mAdvertiserId = AdvertiseManager.sTempRegistrationId;
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java
index 283a098..f85dc0a 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java
@@ -589,15 +589,16 @@
AdvertiseData periodicData = new AdvertiseData.Builder().build();
int duration = 1;
int maxExtAdvEvents = 2;
+ int serverIf = 3;
IAdvertisingSetCallback callback = mock(IAdvertisingSetCallback.class);
mBinder.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, duration, maxExtAdvEvents, callback,
+ periodicData, duration, maxExtAdvEvents, serverIf, callback,
mAttributionSource, SynchronousResultReceiver.get());
verify(mService).startAdvertisingSet(parameters, advertiseData, scanResponse,
- periodicParameters, periodicData, duration, maxExtAdvEvents, callback,
- mAttributionSource);
+ periodicParameters, periodicData, duration, maxExtAdvEvents,
+ serverIf, callback, mAttributionSource);
}
@Test
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 23eccd2..21b167f 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -958,6 +958,10 @@
method @NonNull public android.bluetooth.le.AdvertisingSetParameters.Builder setOwnAddressType(int);
}
+ public final class BluetoothLeAdvertiser {
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT}) public void startAdvertisingSet(@NonNull android.bluetooth.le.AdvertisingSetParameters, @Nullable android.bluetooth.le.AdvertiseData, @Nullable android.bluetooth.le.AdvertiseData, @Nullable android.bluetooth.le.PeriodicAdvertisingParameters, @Nullable android.bluetooth.le.AdvertiseData, int, int, @Nullable android.bluetooth.BluetoothGattServer, @Nullable android.bluetooth.le.AdvertisingSetCallback, @NonNull android.os.Handler);
+ }
+
public final class BluetoothLeScanner {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.UPDATE_DEVICE_STATS}) public void startScanFromSource(android.os.WorkSource, android.bluetooth.le.ScanCallback);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.UPDATE_DEVICE_STATS}) public void startScanFromSource(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.os.WorkSource, android.bluetooth.le.ScanCallback);
diff --git a/framework/java/android/bluetooth/BluetoothGattServer.java b/framework/java/android/bluetooth/BluetoothGattServer.java
index 75261bc..b5e18de 100644
--- a/framework/java/android/bluetooth/BluetoothGattServer.java
+++ b/framework/java/android/bluetooth/BluetoothGattServer.java
@@ -455,6 +455,15 @@
}
/**
+ * Get the identifier of the BluetoothGattServer, or 0 if it is closed
+ *
+ * @hide
+ */
+ public int getServerIf() {
+ return mServerIf;
+ }
+
+ /**
* Returns a characteristic with given handle.
*
* @hide
diff --git a/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 342da41..9e8dcde 100644
--- a/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -18,11 +18,15 @@
import static android.bluetooth.le.BluetoothLeUtils.getSyncTimeout;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
@@ -374,10 +378,65 @@
@RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
- PeriodicAdvertisingParameters periodicParameters,
- AdvertiseData periodicData, int duration,
- int maxExtendedAdvertisingEvents, AdvertisingSetCallback callback,
+ PeriodicAdvertisingParameters periodicParameters, AdvertiseData periodicData,
+ int duration, int maxExtendedAdvertisingEvents, AdvertisingSetCallback callback,
Handler handler) {
+ startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
+ periodicData, duration, maxExtendedAdvertisingEvents, null, callback, handler);
+ }
+
+ /**
+ * Creates a new advertising set. If operation succeed, device will start advertising. This
+ * method returns immediately, the operation status is delivered through
+ * {@code callback.onAdvertisingSetStarted()}.
+ *
+ * <p>If the {@code gattServer} is provided, connections to this advertisement will only see
+ * the services/characteristics in this server, rather than the union of all GATT
+ * services (across all opened servers).
+ *
+ * @param parameters Advertising set parameters.
+ * @param advertiseData Advertisement data to be broadcasted. Size must not exceed {@link
+ * BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the advertisement is connectable,
+ * three bytes will be added for flags.
+ * @param scanResponse Scan response associated with the advertisement data. Size must not
+ * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
+ * @param periodicParameters Periodic advertisng parameters. If null, periodic advertising will
+ * not be started.
+ * @param periodicData Periodic advertising data. Size must not exceed {@link
+ * BluetoothAdapter#getLeMaximumAdvertisingDataLength}
+ * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to 65535
+ * (655,350 ms). 0 means advertising should continue until stopped.
+ * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
+ * controller shall attempt to send prior to terminating the extended advertising, even if the
+ * duration has not expired. Valid range is from 1 to 255. 0 means no maximum.
+ * @param gattServer the GATT server that will "own" connections derived from this advertising
+ * set.
+ * @param callback Callback for advertising set.
+ * @param handler Thread upon which the callbacks will be invoked.
+ * @throws IllegalArgumentException When any of the data parameter exceed the maximum allowable
+ * size, or unsupported advertising PHY is selected, or when attempt to use Periodic Advertising
+ * feature is made when it's not supported by the controller, or when
+ * maxExtendedAdvertisingEvents is used on a controller that doesn't support the LE Extended
+ * Advertising
+ *
+ * @hide
+ */
+ @SystemApi
+ @SuppressLint("ExecutorRegistration")
+ @RequiresBluetoothAdvertisePermission
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ android.Manifest.permission.BLUETOOTH_ADVERTISE,
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ })
+ public void
+ startAdvertisingSet(@NonNull AdvertisingSetParameters parameters,
+ @Nullable AdvertiseData advertiseData, @Nullable AdvertiseData scanResponse,
+ @Nullable PeriodicAdvertisingParameters periodicParameters,
+ @Nullable AdvertiseData periodicData, int duration,
+ int maxExtendedAdvertisingEvents, @Nullable BluetoothGattServer gattServer,
+ @Nullable AdvertisingSetCallback callback,
+ @SuppressLint("ListenerLast") @NonNull Handler handler) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
@@ -470,14 +529,18 @@
try {
final SynchronousResultReceiver recv = SynchronousResultReceiver.get();
gatt.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, duration, maxExtendedAdvertisingEvents, wrapped,
- mAttributionSource, recv);
+ periodicData, duration, maxExtendedAdvertisingEvents,
+ gattServer == null ? 0 : gattServer.getServerIf(), wrapped, mAttributionSource,
+ recv);
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
} catch (TimeoutException | RemoteException e) {
Log.e(TAG, "Failed to start advertising set - ", e);
postStartSetFailure(handler, callback,
AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
return;
+ } catch (SecurityException e) {
+ mCallbackWrappers.remove(callback);
+ throw e;
}
}
diff --git a/system/binder/android/bluetooth/IBluetoothGatt.aidl b/system/binder/android/bluetooth/IBluetoothGatt.aidl
index d3ccc25..d8e877d 100644
--- a/system/binder/android/bluetooth/IBluetoothGatt.aidl
+++ b/system/binder/android/bluetooth/IBluetoothGatt.aidl
@@ -67,7 +67,7 @@
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
void startAdvertisingSet(in AdvertisingSetParameters parameters, in AdvertiseData advertiseData,
in AdvertiseData scanResponse, in PeriodicAdvertisingParameters periodicParameters,
- in AdvertiseData periodicData, in int duration, in int maxExtAdvEvents,
+ in AdvertiseData periodicData, in int duration, in int maxExtAdvEvents, in int gattServerIf,
in IAdvertisingSetCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
void stopAdvertisingSet(in IAdvertisingSetCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
diff --git a/system/btif/src/btif_ble_advertiser.cc b/system/btif/src/btif_ble_advertiser.cc
index c86d956..9e17774 100644
--- a/system/btif/src/btif_ble_advertiser.cc
+++ b/system/btif/src/btif_ble_advertiser.cc
@@ -190,17 +190,17 @@
timeout_s * 100, jni_thread_wrapper(FROM_HERE, timeout_cb)));
}
- void StartAdvertisingSet(int reg_id, IdTxPowerStatusCallback cb,
- AdvertiseParameters params,
- std::vector<uint8_t> advertise_data,
- std::vector<uint8_t> scan_response_data,
- PeriodicAdvertisingParameters periodic_params,
- std::vector<uint8_t> periodic_data,
- uint16_t duration, uint8_t maxExtAdvEvents,
- IdStatusCallback timeout_cb) override {
+ uint8_t StartAdvertisingSet(int reg_id, IdTxPowerStatusCallback cb,
+ AdvertiseParameters params,
+ std::vector<uint8_t> advertise_data,
+ std::vector<uint8_t> scan_response_data,
+ PeriodicAdvertisingParameters periodic_params,
+ std::vector<uint8_t> periodic_data,
+ uint16_t duration, uint8_t maxExtAdvEvents,
+ IdStatusCallback timeout_cb) override {
VLOG(1) << __func__;
- if (!BleAdvertisingManager::IsInitialized()) return;
+ if (!BleAdvertisingManager::IsInitialized()) return {};
tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
parseParams(p_params, params);
@@ -215,6 +215,8 @@
std::move(scan_response_data), base::Owned(p_periodic_params),
std::move(periodic_data), duration, maxExtAdvEvents,
jni_thread_wrapper(FROM_HERE, timeout_cb)));
+
+ return {};
}
void SetPeriodicAdvertisingParameters(
diff --git a/system/include/hardware/ble_advertiser.h b/system/include/hardware/ble_advertiser.h
index f18937e..38b3f4e 100644
--- a/system/include/hardware/ble_advertiser.h
+++ b/system/include/hardware/ble_advertiser.h
@@ -118,8 +118,10 @@
/** Start the advertising set. This include registering, setting all
* parameters and data, and enabling it. |register_cb| is called when the set
* is advertising. |timeout_cb| is called when the timeout_s have passed.
- * |reg_id| is the callback id assigned from upper layer */
- virtual void StartAdvertisingSet(
+ * |reg_id| is the callback id assigned from upper layer
+ *
+ * @return The advertising set ID (at the HCI layer) */
+ virtual uint8_t StartAdvertisingSet(
int reg_id, IdTxPowerStatusCallback register_cb,
AdvertiseParameters params, std::vector<uint8_t> advertise_data,
std::vector<uint8_t> scan_response_data,
diff --git a/system/main/shim/le_advertising_manager.cc b/system/main/shim/le_advertising_manager.cc
index 5881bdb..83866f8 100644
--- a/system/main/shim/le_advertising_manager.cc
+++ b/system/main/shim/le_advertising_manager.cc
@@ -161,14 +161,14 @@
set_terminated_callback, bluetooth::shim::GetGdShimHandler());
}
- void StartAdvertisingSet(int reg_id, IdTxPowerStatusCallback register_cb,
- AdvertiseParameters params,
- std::vector<uint8_t> advertise_data,
- std::vector<uint8_t> scan_response_data,
- PeriodicAdvertisingParameters periodic_params,
- std::vector<uint8_t> periodic_data,
- uint16_t duration, uint8_t maxExtAdvEvents,
- IdStatusCallback timeout_cb) {
+ uint8_t StartAdvertisingSet(int reg_id, IdTxPowerStatusCallback register_cb,
+ AdvertiseParameters params,
+ std::vector<uint8_t> advertise_data,
+ std::vector<uint8_t> scan_response_data,
+ PeriodicAdvertisingParameters periodic_params,
+ std::vector<uint8_t> periodic_data,
+ uint16_t duration, uint8_t maxExtAdvEvents,
+ IdStatusCallback timeout_cb) {
LOG(INFO) << __func__ << " in shim layer";
bluetooth::hci::AdvertisingConfig config{};
@@ -228,6 +228,8 @@
BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Le advert started",
base::StringPrintf("advert_id:%d", reg_id));
+
+ return id;
}
void SetPeriodicAdvertisingParameters(
diff --git a/system/rust/src/gatt/ffi.rs b/system/rust/src/gatt/ffi.rs
index b21e462..29fbe6f 100644
--- a/system/rust/src/gatt/ffi.rs
+++ b/system/rust/src/gatt/ffi.rs
@@ -14,7 +14,7 @@
};
use super::{
- arbiter::with_arbiter,
+ arbiter::{self, with_arbiter},
channel::AttTransport,
ids::{AdvertiserId, AttHandle, ConnectionId, ServerId, TransportIndex},
server::gatt_database::{AttPermissions, GattCharacteristicWithHandle, GattServiceWithHandle},
@@ -94,6 +94,10 @@
// connection
fn is_connection_isolated(conn_id: u16) -> bool;
+
+ // arbitration
+ fn associate_server_with_advertiser(server_id: u8, advertiser_id: u8);
+ fn clear_advertiser(advertiser_id: u8);
}
}
@@ -239,6 +243,24 @@
with_arbiter(|arbiter| arbiter.is_connection_isolated(ConnectionId(conn_id)))
}
+fn associate_server_with_advertiser(server_id: u8, advertiser_id: u8) {
+ if !rust_event_loop_is_enabled() {
+ return;
+ }
+
+ arbiter::with_arbiter(move |arbiter| {
+ arbiter.associate_server_with_advertiser(ServerId(server_id), AdvertiserId(advertiser_id))
+ })
+}
+
+fn clear_advertiser(advertiser_id: u8) {
+ if !rust_event_loop_is_enabled() {
+ return;
+ }
+
+ arbiter::with_arbiter(move |arbiter| arbiter.clear_advertiser(AdvertiserId(advertiser_id)))
+}
+
#[cfg(test)]
mod test {
use super::*;
diff --git a/system/service/test/low_energy_advertiser_unittest.cc b/system/service/test/low_energy_advertiser_unittest.cc
index ca03340..297d9d7 100644
--- a/system/service/test/low_energy_advertiser_unittest.cc
+++ b/system/service/test/low_energy_advertiser_unittest.cc
@@ -60,13 +60,13 @@
AdvertiseParameters, std::vector<uint8_t>,
std::vector<uint8_t>, int, StatusCallback));
MOCK_METHOD10(StartAdvertisingSet,
- void(int reg_id, IdTxPowerStatusCallback cb,
- AdvertiseParameters params,
- std::vector<uint8_t> advertise_data,
- std::vector<uint8_t> scan_response_data,
- PeriodicAdvertisingParameters periodic_params,
- std::vector<uint8_t> periodic_data, uint16_t duration,
- uint8_t maxExtAdvEvents, IdStatusCallback timeout_cb));
+ uint8_t(int reg_id, IdTxPowerStatusCallback cb,
+ AdvertiseParameters params,
+ std::vector<uint8_t> advertise_data,
+ std::vector<uint8_t> scan_response_data,
+ PeriodicAdvertisingParameters periodic_params,
+ std::vector<uint8_t> periodic_data, uint16_t duration,
+ uint8_t maxExtAdvEvents, IdStatusCallback timeout_cb));
MOCK_METHOD3(SetPeriodicAdvertisingParameters,
void(int, PeriodicAdvertisingParameters, StatusCallback));
MOCK_METHOD3(SetPeriodicAdvertisingData,