Skip to content
Open
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
3433452
Add initial Tauri v2 support
haslinghuis Mar 11, 2025
8f14ff4
Add native tauri check
haslinghuis Mar 12, 2025
ede1c21
Add Tauri v2 shell:allow-open capability
haslinghuis Sep 5, 2025
1ca8699
Update
haslinghuis Oct 23, 2025
f8dab3c
Add DockerFile (needs testing)
haslinghuis Oct 23, 2025
1da5d9f
Update edition
haslinghuis Oct 23, 2025
617ff0a
Update DOCKER.MD
haslinghuis Oct 24, 2025
f84571d
Fix app security capabilities
haslinghuis Oct 24, 2025
80ac855
Fix outdated versions
haslinghuis Oct 24, 2025
5e028da
Fix shell open
haslinghuis Oct 24, 2025
eb42e49
Add android commands
haslinghuis Oct 24, 2025
68701cf
Use yarn for docker
haslinghuis Oct 24, 2025
bdf976e
Use cargo
haslinghuis Oct 24, 2025
166339d
Fix yarn tauri:android:dev
haslinghuis Oct 24, 2025
a076fa6
isTauri does not work with Android
haslinghuis Oct 24, 2025
e39b6a8
Update path for ADB
haslinghuis Oct 24, 2025
f3584f2
Use run-script-os
haslinghuis Oct 24, 2025
4684bd9
Fix HMR on android
haslinghuis Oct 24, 2025
cc1fc43
Remove redundant alias
haslinghuis Oct 24, 2025
544a4cb
Avoid device offline races
haslinghuis Oct 24, 2025
a9626ea
👾
haslinghuis Oct 24, 2025
6303719
add equivalent boot completion check to Windows version
haslinghuis Oct 24, 2025
cada7cc
Fix sonar
haslinghuis Oct 24, 2025
d472ec7
Nitpicks
haslinghuis Oct 24, 2025
a007672
Added support for tauriserial
haslinghuis Oct 25, 2025
c1e2b06
Added support for tauriserial II
haslinghuis Oct 25, 2025
6dafd31
Update DOCKER.md
haslinghuis Oct 25, 2025
48b74e2
Update
haslinghuis Oct 25, 2025
25962ab
Fix broken pipe, reconnect, unplug
haslinghuis Oct 25, 2025
abc5631
Fix some sonar issues
haslinghuis Oct 25, 2025
a988841
Coderabbit refactoring
haslinghuis Oct 25, 2025
ef2294b
Use function not object
haslinghuis Oct 25, 2025
734a3fc
Fix race condition
haslinghuis Oct 25, 2025
8e85239
Remove deadcode after refactoring
haslinghuis Oct 25, 2025
8ba48f9
Fix some more sonar issues but not all
haslinghuis Oct 25, 2025
a1d67e2
cargo update
haslinghuis Oct 25, 2025
cb7b589
ci: simplify to node-only, add workflow_dispatch test wrapper
haslinghuis Oct 25, 2025
01cc1be
release: add Tauri desktop builds (dmg/nsis/deb/appimage) and optiona…
haslinghuis Oct 25, 2025
452ef67
release: always build Android APK; setup Android SDK and cache Gradle…
haslinghuis Oct 25, 2025
73a9e76
ci: run on pull_request and push; upload web-dist artifact to PR; gua…
haslinghuis Oct 25, 2025
b03b13e
ci: add Tauri Linux preview job to build and upload .deb/.AppImage on…
haslinghuis Oct 25, 2025
d8c3480
ci: fix Tauri Linux preview by installing required Linux deps (webkit…
haslinghuis Oct 25, 2025
244c915
CI: fix Tauri Linux preview by building web assets and set correct CW…
haslinghuis Oct 25, 2025
79a182e
Fix tauri.conf.json schema error: remove unsupported *Cwd keys; run w…
haslinghuis Oct 25, 2025
36e6ea3
CI: run Tauri before* commands at repo root (remove `cd ..`) to fix p…
haslinghuis Oct 25, 2025
01b2bce
Rust
haslinghuis Oct 25, 2025
45cdf14
CI+Tauri: point frontendDist to ../src/dist and upload correct web ar…
haslinghuis Oct 25, 2025
c1bf16e
CI: fix Tauri action invocation (use `yarn tauri` so action appends `…
haslinghuis Oct 25, 2025
7d74b82
CI(Linux): install pkg-config, libudev-dev, and libssl-dev to satisfy…
haslinghuis Oct 25, 2025
8289a55
Publish
haslinghuis Oct 26, 2025
0e15d1b
Remove fallback
haslinghuis Oct 26, 2025
596b2d5
Fix artifact-links workflow: trigger on "CI" workflow instead of non-…
haslinghuis Oct 26, 2025
3ebf95e
Fix artifact-links: only run when CI was triggered by pull_request (s…
haslinghuis Oct 26, 2025
a598391
Add permissions to artifact-links workflow (pull-requests: write, act…
haslinghuis Oct 26, 2025
42d8784
Rewrite artifact-links workflow with github-script for better reliabi…
haslinghuis Oct 26, 2025
caad22d
Revert "Switch to Tauri branch for configurator builds"
haslinghuis Oct 26, 2025
4c0399f
Add Android USB support
haslinghuis Nov 10, 2025
188a51b
Initial cleanup
haslinghuis Nov 10, 2025
f3f0436
CR review
haslinghuis Nov 10, 2025
72f6b60
Remove unused import
haslinghuis Nov 10, 2025
6aba010
Missed one
haslinghuis Nov 10, 2025
4ec261e
Always add virtual protocol
haslinghuis Nov 10, 2025
3782d33
Some sonar
haslinghuis Nov 10, 2025
5dd2a2e
Remove logging
haslinghuis Nov 10, 2025
1848e79
Good nitpick
haslinghuis Nov 10, 2025
e3c6152
Address (re)connection issues
haslinghuis Nov 10, 2025
c8d2d3d
Remove Java logging & update patch
haslinghuis Nov 10, 2025
1341146
Fix the patch
haslinghuis Nov 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ repositories {
flatDir{
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
}
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}

dependencies {
Expand Down
2 changes: 1 addition & 1 deletion android/app/capacitor.build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ android {

apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies {

implementation project(':capacitor-plugin-usb-serial')

}

Expand Down
11 changes: 11 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>

<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />

</activity>

<provider
Expand All @@ -38,4 +46,7 @@
<!-- Permissions -->

<uses-permission android:name="android.permission.INTERNET" />

<!-- USB Host feature -->
<uses-feature android:name="android.hardware.usb.host" android:required="true" />
</manifest>
34 changes: 34 additions & 0 deletions android/app/src/main/res/xml/device_filter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- USB device filters for Betaflight-compatible devices -->

<!-- FT232R USB UART -->
<usb-device vendor-id="1027" product-id="24577" />

<!-- STM32 devices -->
<usb-device vendor-id="1155" product-id="12886" /> <!-- STM32 in HID mode -->
<usb-device vendor-id="1155" product-id="14158" /> <!-- STLink Virtual COM Port (NUCLEO boards) -->
<usb-device vendor-id="1155" product-id="22336" /> <!-- STM Electronics Virtual COM Port -->
<usb-device vendor-id="1155" product-id="57105" /> <!-- STM Device in DFU Mode -->

<!-- CP210x devices -->
<usb-device vendor-id="4292" product-id="60000" />
<usb-device vendor-id="4292" product-id="60001" />
<usb-device vendor-id="4292" product-id="60002" />

<!-- GD32 devices -->
<usb-device vendor-id="10473" product-id="394" /> <!-- GD32 VCP -->
<usb-device vendor-id="10473" product-id="393" /> <!-- GD32 DFU Bootloader -->

<!-- AT32 devices -->
<usb-device vendor-id="11836" product-id="22336" /> <!-- AT32 VCP -->
<usb-device vendor-id="11836" product-id="57105" /> <!-- AT32F435 DFU Bootloader -->

<!-- APM32 devices -->
<usb-device vendor-id="12619" product-id="22336" /> <!-- APM32 VCP -->
<usb-device vendor-id="12619" product-id="262" /> <!-- APM32 DFU Bootloader -->

<!-- Raspberry Pi Pico devices -->
<usb-device vendor-id="11914" product-id="9" /> <!-- Raspberry Pi Pico VCP -->
<usb-device vendor-id="11914" product-id="15" /> <!-- Raspberry Pi Pico in Bootloader mode -->
</resources>
3 changes: 3 additions & 0 deletions android/capacitor.settings.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
include ':capacitor-android'
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')

include ':capacitor-plugin-usb-serial'
project(':capacitor-plugin-usb-serial').projectDir = new File('../node_modules/capacitor-plugin-usb-serial/android')
Empty file modified android/gradlew
100644 → 100755
Empty file.
8 changes: 8 additions & 0 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@ include ':app'
include ':capacitor-cordova-android-plugins'
project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/')

dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}

apply from: 'capacitor.settings.gradle'
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"android:release": "vite build && node capacitor.config.generator.mjs && npx cap build android --release",
"format": "prettier --write {src,test}/**/*.{js,vue,css,less}",
"storybook": "start-storybook -p 6006",
"prepare": "husky install"
"prepare": "husky install",
"postinstall": "patch-package"
},
"window": {
"icon": "images/bf_icon_128.png",
Expand All @@ -45,6 +46,7 @@
"@capacitor/core": "^7.0.1",
"@fortawesome/fontawesome-free": "^6.5.2",
"@vitejs/plugin-vue": "^6.0.1",
"capacitor-plugin-usb-serial": "^0.0.6",
"crypto-es": "^2.1.0",
"d3": "^7.9.0",
"djv": "^2.1.4",
Expand Down Expand Up @@ -115,7 +117,9 @@
"lint-staged": "^15.4.3",
"nw-builder": "^3.8.6",
"os": "^0.1.2",
"patch-package": "^8.0.1",
"postcss": "^8.5.3",
"postinstall-postinstall": "^2.1.0",
"prettier": "^3.5.2",
"rollup": "^4.34.9",
"rollup-plugin-copy": "^3.5.0",
Expand Down
353 changes: 353 additions & 0 deletions patches/capacitor-plugin-usb-serial+0.0.6.patch

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/js/gui.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import MSP from "./msp";
import Switchery from "switchery-latest";
import tippy from "tippy.js";
import $ from "jquery";
import { getOS } from "./utils/checkBrowserCompatibility";
import { getOS } from "./utils/checkCompatibility";

const TABS = {};

Expand Down
50 changes: 25 additions & 25 deletions src/js/port_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { serial } from "./serial.js";
import WEBUSBDFU from "./protocols/webusbdfu";
import { reactive } from "vue";
import {
checkBrowserCompatibility,
checkWebBluetoothSupport,
checkWebSerialSupport,
checkWebUSBSupport,
} from "./utils/checkBrowserCompatibility.js";
checkCompatibility,
checkBluetoothSupport,
checkSerialSupport,
checkUsbSupport,
} from "./utils/checkCompatibility.js";

const DEFAULT_PORT = "noselection";
const DEFAULT_BAUDS = 115200;
Expand All @@ -34,11 +34,11 @@ const PortHandler = new (function () {
this.dfuAvailable = false;
this.portAvailable = false;

checkBrowserCompatibility();
checkCompatibility();

this.showBluetoothOption = checkWebBluetoothSupport();
this.showSerialOption = checkWebSerialSupport();
this.showUsbOption = checkWebUSBSupport();
this.showBluetoothOption = checkBluetoothSupport();
this.showSerialOption = checkSerialSupport();
this.showUsbOption = checkUsbSupport();

console.log(`${this.logHead} Bluetooth available: ${this.showBluetoothOption}`);
console.log(`${this.logHead} Serial available: ${this.showSerialOption}`);
Expand All @@ -50,8 +50,8 @@ const PortHandler = new (function () {
})();

PortHandler.initialize = function () {
EventBus.$on("ports-input:request-permission-bluetooth", () => this.requestDevicePermission("webbluetooth"));
EventBus.$on("ports-input:request-permission-serial", () => this.requestDevicePermission("webserial"));
EventBus.$on("ports-input:request-permission-bluetooth", () => this.requestDevicePermission("bluetooth"));
EventBus.$on("ports-input:request-permission-serial", () => this.requestDevicePermission("serial"));
EventBus.$on("ports-input:request-permission-usb", () => this.requestDevicePermission("usb"));
EventBus.$on("ports-input:change", this.onChangeSelectedPort.bind(this));

Expand All @@ -60,9 +60,9 @@ PortHandler.initialize = function () {
const detail = event.detail;

if (detail?.path?.startsWith("bluetooth")) {
this.handleDeviceAdded(detail, "webbluetooth");
this.handleDeviceAdded(detail, "bluetooth");
} else {
this.handleDeviceAdded(detail, "webserial");
this.handleDeviceAdded(detail, "serial");
}
});

Expand All @@ -81,8 +81,8 @@ PortHandler.initialize = function () {
PortHandler.refreshAllDeviceLists = async function () {
// Update all device lists in parallel
return Promise.all([
this.updateDeviceList("webserial"),
this.updateDeviceList("webbluetooth"),
this.updateDeviceList("serial"),
this.updateDeviceList("bluetooth"),
this.updateDeviceList("usb"),
]).then(() => {
this.selectActivePort();
Expand Down Expand Up @@ -112,16 +112,16 @@ PortHandler.removedSerialDevice = function (device) {
if (!devicePath) {
console.warn(`${this.logHead} Device removal event missing path information`, device);
// Still update ports, but don't try to use the undefined path
this.updateDeviceList("webserial").then(() => {
this.updateDeviceList("serial").then(() => {
this.selectActivePort();
});
return;
}

// Update the appropriate ports list based on the device type
const updatePromise = devicePath.startsWith("bluetooth")
? this.updateDeviceList("webbluetooth")
: this.updateDeviceList("webserial");
? this.updateDeviceList("bluetooth")
: this.updateDeviceList("serial");

const wasSelectedPort = this.portPicker.selectedPort === devicePath;

Expand Down Expand Up @@ -274,7 +274,7 @@ PortHandler.handleDeviceAdded = function (device, deviceType) {

// Update the appropriate device list
const updatePromise =
deviceType === "webbluetooth" ? this.updateDeviceList("webbluetooth") : this.updateDeviceList("webserial");
deviceType === "bluetooth" ? this.updateDeviceList("bluetooth") : this.updateDeviceList("serial");

updatePromise.then(() => {
const selectedPort = this.selectActivePort(device);
Expand All @@ -295,19 +295,19 @@ PortHandler.updateDeviceList = async function (deviceType) {

try {
switch (deviceType) {
case "webbluetooth":
case "bluetooth":
if (this.showBluetoothOption) {
ports = await serial.getDevices("webbluetooth");
ports = await serial.getDevices("bluetooth");
}
break;
case "usb":
if (this.showUsbOption) {
ports = await WEBUSBDFU.getDevices();
}
break;
case "webserial":
case "serial":
if (this.showSerialOption) {
ports = await serial.getDevices("webserial");
ports = await serial.getDevices("serial");
}
break;
default:
Expand All @@ -320,7 +320,7 @@ PortHandler.updateDeviceList = async function (deviceType) {

// Update the appropriate properties based on device type
switch (deviceType) {
case "webbluetooth":
case "bluetooth":
this.bluetoothAvailable = orderedPorts.length > 0;
this.currentBluetoothPorts = [...orderedPorts];
console.log(`${this.logHead} Found bluetooth port(s)`, orderedPorts);
Expand All @@ -330,7 +330,7 @@ PortHandler.updateDeviceList = async function (deviceType) {
this.currentUsbPorts = [...orderedPorts];
console.log(`${this.logHead} Found DFU port(s)`, orderedPorts);
break;
case "webserial":
case "serial":
this.portAvailable = orderedPorts.length > 0;
this.currentSerialPorts = [...orderedPorts];
console.log(`${this.logHead} Found serial port(s)`, orderedPorts);
Expand Down
Loading