forked from auracaster/bumble_mirror
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8400ff0802 | |||
| 0ed6aa230b | |||
| 72d5360af9 | |||
| ac3961e763 | |||
| 8385035400 |
@@ -13,7 +13,7 @@ packets coming from the controller are forwarded to the TCP socket.
|
|||||||
Building
|
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.
|
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:
|
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
|
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
|
### Preconditions
|
||||||
When the proxy starts (tapping the "Start" button in the app's main activity), it will try to
|
When the proxy starts (tapping the "Start" button in the app's main activity, or running the proxy
|
||||||
bind to the Bluetooth HAL. This requires disabling SELinux temporarily, and being the only HAL client.
|
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
|
#### Disabling SELinux
|
||||||
Binding to the Bluetooth HCI HAL requires certain SELinux permissions that can't simply be changed
|
Binding to the Bluetooth HCI HAL requires certain SELinux permissions that can't simply be changed
|
||||||
@@ -79,7 +93,33 @@ Airplane Mode, then rebooting. The bluetooth process should, in theory, not rest
|
|||||||
$ adb shell cmd bluetooth_manager disable
|
$ 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`
|
You can start the app from the Android launcher, from Android Studio, or with `adb`
|
||||||
|
|
||||||
#### Launching from the launcher
|
#### Launching from the launcher
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.3.0-alpha11"
|
agp = "8.2.0"
|
||||||
kotlin = "1.9.0"
|
kotlin = "1.9.0"
|
||||||
core-ktx = "1.12.0"
|
core-ktx = "1.12.0"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
|
|||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
package com.github.google.bumble.remotehci
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
class CommandLineInterface {
|
||||||
|
companion object {
|
||||||
|
fun printUsage() {
|
||||||
|
System.out.println("usage: <launch-command> [-h|--help] [<tcp-port>]")
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic fun main(args: Array<String>) {
|
||||||
|
System.out.println("Starting proxy")
|
||||||
|
|
||||||
|
var tcpPort = DEFAULT_TCP_PORT
|
||||||
|
if (args.isNotEmpty()) {
|
||||||
|
if (args[0] == "-h" || args[0] == "--help") {
|
||||||
|
printUsage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
tcpPort = args[0].toInt()
|
||||||
|
} catch (error: NumberFormatException) {
|
||||||
|
System.out.println("ERROR: invalid TCP port argument")
|
||||||
|
printUsage()
|
||||||
|
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}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.3.0-alpha11"
|
agp = "8.2.0"
|
||||||
kotlin = "1.8.10"
|
kotlin = "1.8.10"
|
||||||
core-ktx = "1.9.0"
|
core-ktx = "1.9.0"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user