From 7eb493990fb8775c3ccebe46ead6a6d099d61dbd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 21:43:18 +0000 Subject: [PATCH 1/8] Bump openssl from 0.10.57 to 0.10.60 in /rust Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.57 to 0.10.60. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.57...openssl-v0.10.60) --- updated-dependencies: - dependency-name: openssl dependency-type: indirect ... Signed-off-by: dependabot[bot] --- rust/Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index c4435614..33393397 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1073,9 +1073,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" dependencies = [ "bitflags 2.4.0", "cfg-if", @@ -1105,9 +1105,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.92" +version = "0.9.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" +checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" dependencies = [ "cc", "libc", From 838503540081a9b1e8dbf40e655778c5468ed137 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Sun, 3 Dec 2023 16:35:14 -0800 Subject: [PATCH 2/8] add CLI support --- .../bumble/remotehci/CommandLineInterface.kt | 48 +++++++++++++++++++ .../RemoteHCI/gradle/libs.versions.toml | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt diff --git a/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt b/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt new file mode 100644 index 00000000..182537a6 --- /dev/null +++ b/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt @@ -0,0 +1,48 @@ +package com.github.google.bumble.remotehci + +import java.io.IOException + +class CommandLineInterface { + companion object { + @JvmStatic fun main(args: Array) { + System.out.println("Starting proxy") + + var tcpPort = DEFAULT_TCP_PORT + if (args.size >= 1) { + try { + tcpPort = args[0].toInt() + } catch (error: NumberFormatException) { + System.out.println("ERROR: invalid TCP port argument") + return + } + } + + try { + val hciProxy = HciProxy(tcpPort, object : HciProxy.Listener { + override fun onHostConnectionState(connected: Boolean) { + } + + override fun onHciPacketCountChange( + commandPacketsReceived: Int, + aclPacketsReceived: Int, + scoPacketsReceived: Int, + eventPacketsSent: Int, + aclPacketsSent: Int, + scoPacketsSent: Int + ) { + } + + override fun onMessage(message: String?) { + System.out.println(message) + } + + }) + hciProxy.run() + } catch (error: IOException) { + System.err.println("Exception while running HCI Server: $error") + } catch (error: HciProxy.HalException) { + System.err.println("HAL exception: ${error.message}") + } + } + } +} \ No newline at end of file diff --git a/extras/android/RemoteHCI/gradle/libs.versions.toml b/extras/android/RemoteHCI/gradle/libs.versions.toml index a9f80cf9..f2876e89 100644 --- a/extras/android/RemoteHCI/gradle/libs.versions.toml +++ b/extras/android/RemoteHCI/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.3.0-alpha11" +agp = "8.3.0-alpha16" kotlin = "1.8.10" core-ktx = "1.9.0" junit = "4.13.2" From 843466c822416d3880373461800bc8bd30fbcb4d Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Sun, 3 Dec 2023 17:16:25 -0800 Subject: [PATCH 3/8] a few more constants from the spec --- bumble/hci.py | 104 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/bumble/hci.py b/bumble/hci.py index da849bed..28167e95 100644 --- a/bumble/hci.py +++ b/bumble/hci.py @@ -561,6 +561,12 @@ HCI_LE_TRANSMITTER_TEST_V4_COMMAND = hci_c HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND = hci_command_op_code(0x08, 0x007C) HCI_LE_SET_DEFAULT_SUBRATE_COMMAND = hci_command_op_code(0x08, 0x007D) HCI_LE_SUBRATE_REQUEST_COMMAND = hci_command_op_code(0x08, 0x007E) +HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x007F) +HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND = hci_command_op_code(0x08, 0x0082) +HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0083) +HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND = hci_command_op_code(0x08, 0x0084) +HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND = hci_command_op_code(0x08, 0x0085) +HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x0086) # HCI Error Codes @@ -1317,56 +1323,72 @@ HCI_SUPPORTED_COMMANDS_FLAGS = ( ( HCI_LE_SET_DEFAULT_SUBRATE_COMMAND, HCI_LE_SUBRATE_REQUEST_COMMAND, + HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND, + None, + None, + HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND, + HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND, + HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND + ), + # Octet 47 + ( + HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND, + HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND, + None, None, None, None, None, None, - None ) ) # LE Supported Features -HCI_LE_ENCRYPTION_LE_SUPPORTED_FEATURE = 0 -HCI_CONNECTION_PARAMETERS_REQUEST_PROCEDURE_LE_SUPPORTED_FEATURE = 1 -HCI_EXTENDED_REJECT_INDICATION_LE_SUPPORTED_FEATURE = 2 -HCI_PERIPHERAL_INITIATED_FEATURE_EXCHANGE_LE_SUPPORTED_FEATURE = 3 -HCI_LE_PING_LE_SUPPORTED_FEATURE = 4 -HCI_LE_DATA_PACKET_LENGTH_EXTENSION_LE_SUPPORTED_FEATURE = 5 -HCI_LL_PRIVACY_LE_SUPPORTED_FEATURE = 6 -HCI_EXTENDED_SCANNER_FILTER_POLICIES_LE_SUPPORTED_FEATURE = 7 -HCI_LE_2M_PHY_LE_SUPPORTED_FEATURE = 8 -HCI_STABLE_MODULATION_INDEX_TRANSMITTER_LE_SUPPORTED_FEATURE = 9 -HCI_STABLE_MODULATION_INDEX_RECEIVER_LE_SUPPORTED_FEATURE = 10 -HCI_LE_CODED_PHY_LE_SUPPORTED_FEATURE = 11 -HCI_LE_EXTENDED_ADVERTISING_LE_SUPPORTED_FEATURE = 12 -HCI_LE_PERIODIC_ADVERTISING_LE_SUPPORTED_FEATURE = 13 -HCI_CHANNEL_SELECTION_ALGORITHM_2_LE_SUPPORTED_FEATURE = 14 -HCI_LE_POWER_CLASS_1_LE_SUPPORTED_FEATURE = 15 -HCI_MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE_LE_SUPPORTED_FEATURE = 16 -HCI_CONNECTION_CTE_REQUEST_LE_SUPPORTED_FEATURE = 17 -HCI_CONNECTION_CTE_RESPONSE_LE_SUPPORTED_FEATURE = 18 -HCI_CONNECTIONLESS_CTE_TRANSMITTER_LE_SUPPORTED_FEATURE = 19 -HCI_CONNECTIONLESS_CTR_RECEIVER_LE_SUPPORTED_FEATURE = 20 -HCI_ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION_LE_SUPPORTED_FEATURE = 21 -HCI_ANTENNA_SWITCHING_DURING_CTE_RECEPTION_LE_SUPPORTED_FEATURE = 22 -HCI_RECEIVING_CONSTANT_TONE_EXTENSIONS_LE_SUPPORTED_FEATURE = 23 -HCI_PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER_LE_SUPPORTED_FEATURE = 24 -HCI_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT_LE_SUPPORTED_FEATURE = 25 -HCI_SLEEP_CLOCK_ACCURACY_UPDATES_LE_SUPPORTED_FEATURE = 26 -HCI_REMOTE_PUBLIC_KEY_VALIDATION_LE_SUPPORTED_FEATURE = 27 -HCI_CONNECTED_ISOCHRONOUS_STREAM_CENTRAL_LE_SUPPORTED_FEATURE = 28 -HCI_CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL_LE_SUPPORTED_FEATURE = 29 -HCI_ISOCHRONOUS_BROADCASTER_LE_SUPPORTED_FEATURE = 30 -HCI_SYNCHRONIZED_RECEIVER_LE_SUPPORTED_FEATURE = 31 -HCI_CONNECTED_ISOCHRONOUS_STREAM_LE_SUPPORTED_FEATURE = 32 -HCI_LE_POWER_CONTROL_REQUEST_LE_SUPPORTED_FEATURE = 33 -HCI_LE_POWER_CONTROL_REQUEST_DUP_LE_SUPPORTED_FEATURE = 34 -HCI_LE_PATH_LOSS_MONITORING_LE_SUPPORTED_FEATURE = 35 -HCI_PERIODIC_ADVERTISING_ADI_SUPPORT_LE_SUPPORTED_FEATURE = 36 -HCI_CONNECTION_SUBRATING_LE_SUPPORTED_FEATURE = 37 -HCI_CONNECTION_SUBRATING_HOST_SUPPORT_LE_SUPPORTED_FEATURE = 38 -HCI_CHANNEL_CLASSIFICATION_LE_SUPPORTED_FEATURE = 39 +# See Bluetooth spec @ Vol 6, Part B, 4.6 FEATURE SUPPORT +HCI_LE_ENCRYPTION_LE_SUPPORTED_FEATURE = 0 +HCI_CONNECTION_PARAMETERS_REQUEST_PROCEDURE_LE_SUPPORTED_FEATURE = 1 +HCI_EXTENDED_REJECT_INDICATION_LE_SUPPORTED_FEATURE = 2 +HCI_PERIPHERAL_INITIATED_FEATURE_EXCHANGE_LE_SUPPORTED_FEATURE = 3 +HCI_LE_PING_LE_SUPPORTED_FEATURE = 4 +HCI_LE_DATA_PACKET_LENGTH_EXTENSION_LE_SUPPORTED_FEATURE = 5 +HCI_LL_PRIVACY_LE_SUPPORTED_FEATURE = 6 +HCI_EXTENDED_SCANNER_FILTER_POLICIES_LE_SUPPORTED_FEATURE = 7 +HCI_LE_2M_PHY_LE_SUPPORTED_FEATURE = 8 +HCI_STABLE_MODULATION_INDEX_TRANSMITTER_LE_SUPPORTED_FEATURE = 9 +HCI_STABLE_MODULATION_INDEX_RECEIVER_LE_SUPPORTED_FEATURE = 10 +HCI_LE_CODED_PHY_LE_SUPPORTED_FEATURE = 11 +HCI_LE_EXTENDED_ADVERTISING_LE_SUPPORTED_FEATURE = 12 +HCI_LE_PERIODIC_ADVERTISING_LE_SUPPORTED_FEATURE = 13 +HCI_CHANNEL_SELECTION_ALGORITHM_2_LE_SUPPORTED_FEATURE = 14 +HCI_LE_POWER_CLASS_1_LE_SUPPORTED_FEATURE = 15 +HCI_MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE_LE_SUPPORTED_FEATURE = 16 +HCI_CONNECTION_CTE_REQUEST_LE_SUPPORTED_FEATURE = 17 +HCI_CONNECTION_CTE_RESPONSE_LE_SUPPORTED_FEATURE = 18 +HCI_CONNECTIONLESS_CTE_TRANSMITTER_LE_SUPPORTED_FEATURE = 19 +HCI_CONNECTIONLESS_CTR_RECEIVER_LE_SUPPORTED_FEATURE = 20 +HCI_ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION_LE_SUPPORTED_FEATURE = 21 +HCI_ANTENNA_SWITCHING_DURING_CTE_RECEPTION_LE_SUPPORTED_FEATURE = 22 +HCI_RECEIVING_CONSTANT_TONE_EXTENSIONS_LE_SUPPORTED_FEATURE = 23 +HCI_PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER_LE_SUPPORTED_FEATURE = 24 +HCI_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT_LE_SUPPORTED_FEATURE = 25 +HCI_SLEEP_CLOCK_ACCURACY_UPDATES_LE_SUPPORTED_FEATURE = 26 +HCI_REMOTE_PUBLIC_KEY_VALIDATION_LE_SUPPORTED_FEATURE = 27 +HCI_CONNECTED_ISOCHRONOUS_STREAM_CENTRAL_LE_SUPPORTED_FEATURE = 28 +HCI_CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL_LE_SUPPORTED_FEATURE = 29 +HCI_ISOCHRONOUS_BROADCASTER_LE_SUPPORTED_FEATURE = 30 +HCI_SYNCHRONIZED_RECEIVER_LE_SUPPORTED_FEATURE = 31 +HCI_CONNECTED_ISOCHRONOUS_STREAM_LE_SUPPORTED_FEATURE = 32 +HCI_LE_POWER_CONTROL_REQUEST_LE_SUPPORTED_FEATURE = 33 +HCI_LE_POWER_CONTROL_REQUEST_DUP_LE_SUPPORTED_FEATURE = 34 +HCI_LE_PATH_LOSS_MONITORING_LE_SUPPORTED_FEATURE = 35 +HCI_PERIODIC_ADVERTISING_ADI_SUPPORT_LE_SUPPORTED_FEATURE = 36 +HCI_CONNECTION_SUBRATING_LE_SUPPORTED_FEATURE = 37 +HCI_CONNECTION_SUBRATING_HOST_SUPPORT_LE_SUPPORTED_FEATURE = 38 +HCI_CHANNEL_CLASSIFICATION_LE_SUPPORTED_FEATURE = 39 +HCI_ADVERTISING_CODING_SELECTION_LE_SUPPORTED_FEATURE = 40 +HCI_ADVERTISING_CODING_SELECTION_HOST_SUPPORT_LE_SUPPORTED_FEATURE = 41 +HCI_PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER_LE_SUPPORTED_FEATURE = 43 +HCI_PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER_LE_SUPPORTED_FEATURE = 44 HCI_LE_SUPPORTED_FEATURES_NAMES = { flag: feature_name for (feature_name, flag) in globals().items() From ac3961e763cd236f5cbe694b3d23700d588f8b27 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Sun, 3 Dec 2023 17:50:42 -0800 Subject: [PATCH 4/8] add doc --- docs/mkdocs/src/extras/android_remote_hci.md | 66 ++++++++++++++++---- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/docs/mkdocs/src/extras/android_remote_hci.md b/docs/mkdocs/src/extras/android_remote_hci.md index 4eab132e..735c31be 100644 --- a/docs/mkdocs/src/extras/android_remote_hci.md +++ b/docs/mkdocs/src/extras/android_remote_hci.md @@ -1,19 +1,19 @@ ANDROID REMOTE HCI APP ====================== -This application allows using an android phone's built-in Bluetooth controller with +This application allows using an android phone's built-in Bluetooth controller with a Bumble host stack running outside the phone (typically a development laptop or desktop). The app runs an HCI proxy between a TCP socket on the "outside" and the Bluetooth HCI HAL -on the "inside". (See [this page](https://source.android.com/docs/core/connect/bluetooth) for a high level +on the "inside". (See [this page](https://source.android.com/docs/core/connect/bluetooth) for a high level description of the Android Bluetooth HCI HAL). -The HCI packets received on the TCP socket are forwarded to the phone's controller, and the +The HCI packets received on the TCP socket are forwarded to the phone's controller, and the packets coming from the controller are forwarded to the TCP socket. Building -------- -You can build the app by running `./gradlew build` (use `gradlew.bat` on Windows) from the `RemoteHCI` top level directory. +You can build the app by running `./gradlew build` (use `gradlew.bat` on Windows) from the `extras/android/RemoteHCI` top level directory. You can also build with Android Studio: open the `RemoteHCI` project. You can build and/or debug from there. If the build succeeds, you can find the app APKs (debug and release) at: @@ -25,9 +25,23 @@ If the build succeeds, you can find the app APKs (debug and release) at: Running ------- +!!! note + In the following examples, it is assumed that shell commands are executed while in the + app's root directory, `extras/android/RemoteHCI`. If you are in a different directory, + adjust the relative paths accordingly. + ### Preconditions -When the proxy starts (tapping the "Start" button in the app's main activity), it will try to -bind to the Bluetooth HAL. This requires disabling SELinux temporarily, and being the only HAL client. +When the proxy starts (tapping the "Start" button in the app's main activity, or running the proxy +from an `adb shell` command line), it will try to bind to the Bluetooth HAL. +This requires that there is no other HAL client, and requires certain privileges. +For running as a regular app, this requires disabling SELinux temporarily. +For running as a command-line executable, this just requires a root shell. + +#### Root Shell +!!! tip "Restart `adb` as root" + ```bash + $ adb root + ``` #### Disabling SELinux Binding to the Bluetooth HCI HAL requires certain SELinux permissions that can't simply be changed @@ -56,8 +70,8 @@ development phone). This state will also reset to the normal SELinux enforcement when you reboot. #### Stopping the bluetooth process -Since the Bluetooth HAL service can only accept one client, and that in normal conditions -that client is the Android's bluetooth stack, it is required to first shut down the +Since the Bluetooth HAL service can only accept one client, and that in normal conditions +that client is the Android's bluetooth stack, it is required to first shut down the Android bluetooth stack process. !!! tip "Checking if the Bluetooth process is running" @@ -79,7 +93,33 @@ Airplane Mode, then rebooting. The bluetooth process should, in theory, not rest $ adb shell cmd bluetooth_manager disable ``` -### Starting the app +### Running as a command line app + +You push the built APK to a temporary location on the phone's filesystem, then launch the command +line executable with an `adb shell` command. + +!!! tip "Pushing the executable" + ```bash + $ adb push app/build/outputs/apk/release/app-release-unsigned.apk /data/local/tmp/remotehci.apk + ``` + Do this every time you rebuild. Alternatively, you can push the `debug` APK instead: + ```bash + $ adb push app/build/outputs/apk/debug/app-debug.apk /data/local/tmp/remotehci.apk + ``` + +!!! tip "Start the proxy from the command line" + ```bash + adb shell "CLASSPATH=/data/local/tmp/remotehci.apk app_process /system/bin com.github.google.bumble.remotehci.CommandLineInterface" + ``` + This will run the proxy, listening on the default TCP port. + If you want a different port, pass it as a command line parameter + +!!! tip "Start the proxy from the command line with a specific TCP port" + ```bash + adb shell "CLASSPATH=/data/local/tmp/remotehci.apk app_process /system/bin com.github.google.bumble.remotehci.CommandLineInterface 12345" + ``` + +### Running as a normal app You can start the app from the Android launcher, from Android Studio, or with `adb` #### Launching from the launcher @@ -103,11 +143,11 @@ automatically start the proxy, and/or set the port number. #### Selecting a TCP port The RemoteHCI app's main activity has a "TCP Port" setting where you can change the port on -which the proxy is accepting connections. If the default value isn't suitable, you can +which the proxy is accepting connections. If the default value isn't suitable, you can change it there (you can also use the special value 0 to let the OS assign a port number for you). ### Connecting to the proxy -To connect the Bumble stack to the proxy, you need to be able to reach the phone's network +To connect the Bumble stack to the proxy, you need to be able to reach the phone's network stack. This can be done over the phone's WiFi connection, or, alternatively, using an `adb` TCP forward (which should be faster than over WiFi). @@ -116,7 +156,7 @@ TCP forward (which should be faster than over WiFi). ```bash $ adb forward tcp: tcp: ``` - Where ```` is the port number for a listening socket on your laptop or + Where ```` is the port number for a listening socket on your laptop or desktop machine, and is the TCP port selected in the app's user interface. Those two ports may be the same, of course. For example, with the default TCP port 9993: @@ -125,7 +165,7 @@ TCP forward (which should be faster than over WiFi). ``` Once you've ensured that you can reach the proxy's TCP port on the phone, either directly or -via an `adb` forward, you can then use it as a Bumble transport, using the transport name: +via an `adb` forward, you can then use it as a Bumble transport, using the transport name: ``tcp-client::`` syntax. !!! example "Connecting a Bumble client" From 72d5360af9ceecbbcd84084f499dc7b74dfb3585 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Sun, 3 Dec 2023 18:06:54 -0800 Subject: [PATCH 5/8] keep projects compatible with Android Studio Hedgehog --- extras/android/BtBench/gradle/libs.versions.toml | 2 +- extras/android/RemoteHCI/gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/android/BtBench/gradle/libs.versions.toml b/extras/android/BtBench/gradle/libs.versions.toml index 03d3e584..26945a9e 100644 --- a/extras/android/BtBench/gradle/libs.versions.toml +++ b/extras/android/BtBench/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.3.0-alpha11" +agp = "8.2.0" kotlin = "1.9.0" core-ktx = "1.12.0" junit = "4.13.2" diff --git a/extras/android/RemoteHCI/gradle/libs.versions.toml b/extras/android/RemoteHCI/gradle/libs.versions.toml index f2876e89..8bdfdc75 100644 --- a/extras/android/RemoteHCI/gradle/libs.versions.toml +++ b/extras/android/RemoteHCI/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.3.0-alpha16" +agp = "8.2.0" kotlin = "1.8.10" core-ktx = "1.9.0" junit = "4.13.2" From 0ed6aa230befa687c4641debf232b465c4f7a575 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Mon, 4 Dec 2023 00:32:04 -0800 Subject: [PATCH 6/8] address PR comment --- .../github/google/bumble/remotehci/CommandLineInterface.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt b/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt index 182537a6..9b387a00 100644 --- a/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt +++ b/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt @@ -8,7 +8,11 @@ class CommandLineInterface { System.out.println("Starting proxy") var tcpPort = DEFAULT_TCP_PORT - if (args.size >= 1) { + if (args.isNotEmpty()) { + if (args[0] == "-h" || args[0] == "--help") { + System.out.println("usage: [-h|--help] []") + return + } try { tcpPort = args[0].toInt() } catch (error: NumberFormatException) { From 8400ff080295a098336ba5441a85990541ad6247 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Mon, 4 Dec 2023 00:37:28 -0800 Subject: [PATCH 7/8] shared usage printer --- .../github/google/bumble/remotehci/CommandLineInterface.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt b/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt index 9b387a00..2f1b59e7 100644 --- a/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt +++ b/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt @@ -4,19 +4,24 @@ import java.io.IOException class CommandLineInterface { companion object { + fun printUsage() { + System.out.println("usage: [-h|--help] []") + } + @JvmStatic fun main(args: Array) { System.out.println("Starting proxy") var tcpPort = DEFAULT_TCP_PORT if (args.isNotEmpty()) { if (args[0] == "-h" || args[0] == "--help") { - System.out.println("usage: [-h|--help] []") + printUsage() return } try { tcpPort = args[0].toInt() } catch (error: NumberFormatException) { System.out.println("ERROR: invalid TCP port argument") + printUsage() return } } From d6afbc6f4e6ccac2cf1c00e9511fb5d20143060f Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Mon, 4 Dec 2023 20:11:22 +0800 Subject: [PATCH 8/8] Fix ISO packet issues --- bumble/hci.py | 7 +++++-- bumble/transport/common.py | 1 + tests/hci_test.py | 26 ++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/bumble/hci.py b/bumble/hci.py index da849bed..b28ea07a 100644 --- a/bumble/hci.py +++ b/bumble/hci.py @@ -1986,6 +1986,9 @@ class HCI_Packet: if packet_type == HCI_EVENT_PACKET: return HCI_Event.from_bytes(packet) + if packet_type == HCI_ISO_DATA_PACKET: + return HCI_IsoDataPacket.from_bytes(packet) + return HCI_CustomPacket(packet) def __init__(self, name): @@ -6098,7 +6101,7 @@ class HCI_IsoDataPacket(HCI_Packet): if ts_flag: if not should_include_sdu_info: logger.warn(f'Timestamp included when pb_flag={bin(pb_flag)}') - time_stamp, _ = struct.unpack_from(' str: return ( diff --git a/bumble/transport/common.py b/bumble/transport/common.py index 53e52235..ace04da5 100644 --- a/bumble/transport/common.py +++ b/bumble/transport/common.py @@ -42,6 +42,7 @@ HCI_PACKET_INFO: Dict[int, Tuple[int, int, str]] = { hci.HCI_ACL_DATA_PACKET: (2, 2, 'H'), hci.HCI_SYNCHRONOUS_DATA_PACKET: (1, 2, 'B'), hci.HCI_EVENT_PACKET: (1, 1, 'B'), + hci.HCI_ISO_DATA_PACKET: (2, 2, 'H'), } diff --git a/tests/hci_test.py b/tests/hci_test.py index 56073505..1504f200 100644 --- a/tests/hci_test.py +++ b/tests/hci_test.py @@ -32,6 +32,7 @@ from bumble.hci import ( HCI_CustomPacket, HCI_Disconnect_Command, HCI_Event, + HCI_IsoDataPacket, HCI_LE_Add_Device_To_Filter_Accept_List_Command, HCI_LE_Advertising_Report_Event, HCI_LE_Channel_Selection_Algorithm_Event, @@ -486,6 +487,29 @@ def test_custom(): assert packet.payload == data +# ----------------------------------------------------------------------------- +def test_iso_data_packet(): + data = bytes.fromhex( + '05616044002ac9f0a193003c00e83b477b00eba8d41dc018bf1a980f0290afe1e7c37652096697' + '52b6a535a8df61e22931ef5a36281bc77ed6a3206d984bcdabee6be831c699cb50e2' + ) + packet = HCI_IsoDataPacket.from_bytes(data) + assert packet.connection_handle == 0x0061 + assert packet.packet_status_flag == 0 + assert packet.pb_flag == 0x02 + assert packet.ts_flag == 0x01 + assert packet.data_total_length == 68 + assert packet.time_stamp == 2716911914 + assert packet.packet_sequence_number == 147 + assert packet.iso_sdu_length == 60 + assert packet.iso_sdu_fragment == bytes.fromhex( + 'e83b477b00eba8d41dc018bf1a980f0290afe1e7c3765209669752b6a535a8df61e22931ef5a3' + '6281bc77ed6a3206d984bcdabee6be831c699cb50e2' + ) + + assert packet.to_bytes() == data + + # ----------------------------------------------------------------------------- def run_test_events(): test_HCI_Event() @@ -524,6 +548,7 @@ def run_test_commands(): test_HCI_LE_Set_Default_PHY_Command() test_HCI_LE_Set_Extended_Scan_Parameters_Command() test_HCI_LE_Set_Extended_Advertising_Enable_Command() + test_HCI_LE_Setup_ISO_Data_Path_Command() # ----------------------------------------------------------------------------- @@ -532,3 +557,4 @@ if __name__ == '__main__': run_test_commands() test_address() test_custom() + test_iso_data_packet()