Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
barbibulle committed Feb 3, 2025
1 parent 5293d32 commit f368b5e
Show file tree
Hide file tree
Showing 14 changed files with 418 additions and 38 deletions.
1 change: 1 addition & 0 deletions apps/bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,7 @@ def create_scenario(packet_io):
'--att-mtu',
metavar='MTU',
type=click.IntRange(23, 517),
default=517,
help='GATT MTU (gatt-client mode)',
)
@click.option(
Expand Down
14 changes: 14 additions & 0 deletions examples/mobly/bench/one_device_bench_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ def test_l2cap_client_send(self):
final_status = self.dut.bench.waitForRunnerCompletion(runner["id"])
print("### Final status:", final_status)

def test_gatt_client_send(self):
runner = self.dut.bench.runGattClient(
"send", "F1:F1:F1:F1:F1:F1", 128, True, 100, 970, 100, "HIGH"
)
print("### Initial status:", runner)
final_status = self.dut.bench.waitForRunnerCompletion(runner["id"])
print("### Final status:", final_status)

def test_gatt_server_receive(self):
runner = self.dut.bench.runGattServer("receive")
print("### Initial status:", runner)
final_status = self.dut.bench.waitForRunnerCompletion(runner["id"])
print("### Final status:", final_status)


if __name__ == "__main__":
test_runner.main()
6 changes: 3 additions & 3 deletions examples/mobly/bench/sample_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ TestBeds:
- Name: BenchTestBed
Controllers:
AndroidDevice:
- serial: 37211FDJG000DJ
- serial: emulator-5554
local_bt_address: 94:45:60:5E:03:B0

- serial: 23071FDEE001F7
local_bt_address: DC:E5:5B:E5:51:2C
#- serial: 23071FDEE001F7
# local_bt_address: DC:E5:5B:E5:51:2C
2 changes: 1 addition & 1 deletion extras/android/BtBench/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.google.bumble.btbench">
<uses-sdk android:minSdkVersion="30" android:targetSdkVersion="34" />
<uses-sdk android:minSdkVersion="33" android:targetSdkVersion="34" />
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.github.google.bumble.btbench

import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.AdvertiseCallback
import android.bluetooth.le.AdvertiseData
import android.bluetooth.le.AdvertiseSettings
import android.bluetooth.le.AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY
import android.os.Build
import java.util.logging.Logger

private val Log = Logger.getLogger("btbench.advertiser")

class Advertiser(private val bluetoothAdapter: BluetoothAdapter) : AdvertiseCallback() {
@SuppressLint("MissingPermission")
fun start() {
val advertiseSettingsBuilder = AdvertiseSettings.Builder()
.setAdvertiseMode(ADVERTISE_MODE_LOW_LATENCY)
.setConnectable(true)
advertiseSettingsBuilder.setDiscoverable(true)
val advertiseSettings = advertiseSettingsBuilder.build()
val advertiseData = AdvertiseData.Builder().build()
val scanData = AdvertiseData.Builder().setIncludeDeviceName(true).build()
bluetoothAdapter.bluetoothLeAdvertiser.startAdvertising(advertiseSettings, advertiseData, scanData, this)
}

@SuppressLint("MissingPermission")
fun stop() {
bluetoothAdapter.bluetoothLeAdvertiser.stopAdvertising(this)
}

override fun onStartFailure(errorCode: Int) {
Log.warning("failed to start advertising: $errorCode")
}

override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {
Log.info("advertising started: $settingsInEffect")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ private Runner runScenario(AppViewModel model, String mode, String scenario) {
packetIO));
break;

case "gatt-client":
runnable = new GattClient(model, mBluetoothAdapter, mContext,
(PacketIO packetIO) -> createIoClient(model, scenario,
packetIO));
break;

case "gatt-server":
runnable = new GattServer(model, mBluetoothAdapter, mContext,
(PacketIO packetIO) -> createIoClient(model, scenario,
packetIO));
break;

default:
return null;
}
Expand Down Expand Up @@ -277,6 +289,53 @@ public JSONObject runL2capServer(String scenario,
return runner.toJson();
}

@Rpc(description = "Run a scenario in GATT Client mode")
public JSONObject runGattClient(String scenario, String peerBluetoothAddress,
boolean use_2m_phy, int packetCount, int packetSize,
int packetInterval, @RpcOptional String connectionPriority,
@RpcOptional Integer startupDelay) throws JSONException {
// We only support "send" and "ping" for this mode for now
if (!(scenario.equals("send") || scenario.equals("ping"))) {
throw new InvalidParameterException(
"only 'send' and 'ping' are supported for this mode");
}

AppViewModel model = new AppViewModel();
model.setPeerBluetoothAddress(peerBluetoothAddress);
model.setUse2mPhy(use_2m_phy);
model.setSenderPacketCount(packetCount);
model.setSenderPacketSize(packetSize);
model.setSenderPacketInterval(packetInterval);
if (connectionPriority != null) {
model.setConnectionPriority(connectionPriority);
}
if (startupDelay != null) {
model.setStartupDelay(startupDelay);
}
Runner runner = runScenario(model, "gatt-client", scenario);
assert runner != null;
return runner.toJson();
}

@Rpc(description = "Run a scenario in GATT Server mode")
public JSONObject runGattServer(String scenario,
@RpcOptional Integer startupDelay) throws JSONException {
// We only support "receive" and "pong" for this mode for now
if (!(scenario.equals("receive") || scenario.equals("pong"))) {
throw new InvalidParameterException(
"only 'receive' and 'pong' are supported for this mode");
}

AppViewModel model = new AppViewModel();
if (startupDelay != null) {
model.setStartupDelay(startupDelay);
}

Runner runner = runScenario(model, "gatt-server", scenario);
assert runner != null;
return runner.toJson();
}

@Rpc(description = "Stop a Runner")
public JSONObject stopRunner(String runnerId) throws JSONException {
Runner runner = findRunner(runnerId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ open class Connection(
}

@SuppressLint("MissingPermission")
fun disconnect() {
open fun disconnect() {
gatt?.disconnect()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.github.google.bumble.btbench

import java.util.UUID

var CCCD_UUID = UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")

val BENCH_SERVICE_UUID = UUID.fromString("50DB505C-8AC4-4738-8448-3B1D9CC09CC5")
val BENCH_TX_UUID = UUID.fromString("E789C754-41A1-45F4-A948-A0A1A90DBA53")
val BENCH_RX_UUID = UUID.fromString("016A2CC7-E14B-4819-935F-1F56EAE4098D")
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ import kotlin.concurrent.thread

private val Log = Logger.getLogger("btbench.gatt-client")

private var CCCD_UUID = UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")

private val SPEED_SERVICE_UUID = UUID.fromString("50DB505C-8AC4-4738-8448-3B1D9CC09CC5")
private val SPEED_TX_UUID = UUID.fromString("E789C754-41A1-45F4-A948-A0A1A90DBA53")
private val SPEED_RX_UUID = UUID.fromString("016A2CC7-E14B-4819-935F-1F56EAE4098D")


class GattClientConnection(
viewModel: AppViewModel,
Expand All @@ -52,7 +46,8 @@ class GattClientConnection(
super.connect()

// Check if we're already connected and have discovered the services
if (gatt?.getService(SPEED_SERVICE_UUID) != null) {
if (gatt?.getService(BENCH_SERVICE_UUID) != null) {
Log.fine("already connected")
onServicesDiscovered(gatt, BluetoothGatt.GATT_SUCCESS)
}
}
Expand All @@ -63,6 +58,7 @@ class GattClientConnection(
) {
super.onConnectionStateChange(gatt, status, newState)
if (status != BluetoothGatt.GATT_SUCCESS) {
Log.warning("onConnectionStateChange status=$status")
discoveryDone.countDown()
return
}
Expand All @@ -76,35 +72,38 @@ class GattClientConnection(

@SuppressLint("MissingPermission")
override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
Log.fine("onServicesDiscovered")

if (status != BluetoothGatt.GATT_SUCCESS) {
Log.warning("failed to discover services: ${status}")
discoveryDone.countDown()
return
}

// Find the service
val service = gatt!!.getService(SPEED_SERVICE_UUID)
val service = gatt!!.getService(BENCH_SERVICE_UUID)
if (service == null) {
Log.warning("GATT Service not found")
discoveryDone.countDown()
return
}

// Find the RX and TX characteristics
rxCharacteristic = service.getCharacteristic(SPEED_RX_UUID)
rxCharacteristic = service.getCharacteristic(BENCH_RX_UUID)
if (rxCharacteristic == null) {
Log.warning("GATT RX Characteristics not found")
discoveryDone.countDown()
return
}
txCharacteristic = service.getCharacteristic(SPEED_TX_UUID)
txCharacteristic = service.getCharacteristic(BENCH_TX_UUID)
if (txCharacteristic == null) {
Log.warning("GATT TX Characteristics not found")
discoveryDone.countDown()
return
}

// Subscribe to the RX characteristic
Log.fine("subscribing to RX")
gatt.setCharacteristicNotification(rxCharacteristic, true)
val cccdDescriptor = rxCharacteristic!!.getDescriptor(CCCD_UUID)
gatt.writeDescriptor(cccdDescriptor, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
Expand Down Expand Up @@ -132,7 +131,7 @@ class GattClientConnection(
characteristic: BluetoothGattCharacteristic,
value: ByteArray
) {
if (characteristic.uuid == SPEED_RX_UUID && packetSink != null) {
if (characteristic.uuid == BENCH_RX_UUID && packetSink != null) {
val packet = Packet.from(value)
packetSink!!.onPacket(packet)
}
Expand Down Expand Up @@ -163,6 +162,12 @@ class GattClientConnection(
)
}

override
fun disconnect() {
super.disconnect()
discoveryDone.countDown()
}

fun waitForDiscoveryCompletion() {
discoveryDone.await()
}
Expand Down
Loading

0 comments on commit f368b5e

Please sign in to comment.