mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat: Desktop USB serial transport (#4836)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
06c990026f
commit
59408ef46e
19 changed files with 457 additions and 37 deletions
|
|
@ -49,7 +49,7 @@ The module depends on the JVM variants of KMP modules:
|
|||
| `navigation/DesktopSettingsNavigation.kt` | Real settings feature composables wired into nav graph (~35 screens) |
|
||||
| `navigation/DesktopNodeNavigation.kt` | Real adaptive node list-detail + real metrics screens (logs + charts); map routes remain placeholders |
|
||||
| `navigation/DesktopMessagingNavigation.kt` | Real adaptive contacts list-detail + real Messages/Share/QuickChat route screens |
|
||||
| `radio/DesktopRadioInterfaceService.kt` | TCP socket transport with auto-reconnect, heartbeat, and backoff retry |
|
||||
| `radio/DesktopRadioInterfaceService.kt` | TCP, Serial/USB, and BLE transports with auto-reconnect, heartbeat, and backoff retry |
|
||||
| `radio/DesktopMeshServiceController.kt` | Mesh service lifecycle — orchestrates `want_config` handshake chain |
|
||||
| `radio/DesktopMessageQueue.kt` | Message queue for outbound mesh packets |
|
||||
| `ui/firmware/DesktopFirmwareScreen.kt` | Placeholder firmware screen (native DFU is Android-only) |
|
||||
|
|
@ -91,6 +91,7 @@ The module depends on the JVM variants of KMP modules:
|
|||
- [x] Add desktop language picker backed by shared `UiPreferencesDataSource.locale` with live translation updates
|
||||
- [ ] Wire remaining `feature:*` composables (map) into the nav graph
|
||||
- [ ] Move remaining node detail and message composables from `androidMain` to `commonMain`
|
||||
- [ ] Add serial/USB transport for direct radio connection on Desktop
|
||||
- [x] Add serial/USB transport for direct radio connection on Desktop
|
||||
- [x] Add BLE transport (via Kable) for direct radio connection on Desktop
|
||||
- [ ] Add MQTT transport for cloud-connected operation
|
||||
- [x] Package as native distributions (DMG, MSI, DEB) via CI release pipeline
|
||||
|
|
|
|||
|
|
@ -56,7 +56,11 @@ class DesktopRadioInterfaceService(
|
|||
) : RadioInterfaceService {
|
||||
|
||||
override val supportedDeviceTypes: List<org.meshtastic.core.model.DeviceType> =
|
||||
listOf(org.meshtastic.core.model.DeviceType.TCP, org.meshtastic.core.model.DeviceType.BLE)
|
||||
listOf(
|
||||
org.meshtastic.core.model.DeviceType.TCP,
|
||||
org.meshtastic.core.model.DeviceType.BLE,
|
||||
org.meshtastic.core.model.DeviceType.USB,
|
||||
)
|
||||
|
||||
private val _connectionState = MutableStateFlow<ConnectionState>(ConnectionState.Disconnected)
|
||||
override val connectionState: StateFlow<ConnectionState> = _connectionState.asStateFlow()
|
||||
|
|
@ -76,6 +80,7 @@ class DesktopRadioInterfaceService(
|
|||
|
||||
private var transport: TcpTransport? = null
|
||||
private var bleTransport: DesktopBleInterface? = null
|
||||
private var serialTransport: org.meshtastic.core.network.SerialTransport? = null
|
||||
|
||||
init {
|
||||
// Observe radioPrefs to handle asynchronous loads from DataStore
|
||||
|
|
@ -136,6 +141,7 @@ class DesktopRadioInterfaceService(
|
|||
serviceScope.handledLaunch {
|
||||
transport?.sendPacket(bytes)
|
||||
bleTransport?.handleSendToRadio(bytes)
|
||||
serialTransport?.handleSendToRadio(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +176,8 @@ class DesktopRadioInterfaceService(
|
|||
private fun startConnection(address: String) {
|
||||
if (address.startsWith("t")) {
|
||||
startTcpConnection(address.removePrefix("t"))
|
||||
} else if (address.startsWith("s")) {
|
||||
startSerialConnection(address.removePrefix("s"))
|
||||
} else if (address.startsWith("x")) {
|
||||
startBleConnection(address.removePrefix("x"))
|
||||
} else {
|
||||
|
|
@ -179,6 +187,18 @@ class DesktopRadioInterfaceService(
|
|||
}
|
||||
}
|
||||
|
||||
private fun startSerialConnection(portName: String) {
|
||||
transport?.stop()
|
||||
bleTransport?.close()
|
||||
serialTransport?.close()
|
||||
|
||||
val serial = org.meshtastic.core.network.SerialTransport(portName = portName, service = this)
|
||||
serialTransport = serial
|
||||
if (!serial.startConnection()) {
|
||||
onDisconnect(isPermanent = true, errorMessage = "Failed to connect to $portName")
|
||||
}
|
||||
}
|
||||
|
||||
private fun startBleConnection(address: String) {
|
||||
transport?.stop()
|
||||
bleTransport?.close()
|
||||
|
|
@ -228,6 +248,9 @@ class DesktopRadioInterfaceService(
|
|||
bleTransport?.close()
|
||||
bleTransport = null
|
||||
|
||||
serialTransport?.close()
|
||||
serialTransport = null
|
||||
|
||||
// Recreate the service scope
|
||||
serviceScope.cancel("stopping interface")
|
||||
serviceScope = CoroutineScope(dispatchers.io + SupervisorJob())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue