From 129df287e01b571ca99d4e438ed37aec0b3eb1d7 Mon Sep 17 00:00:00 2001 From: Nikita Kulikov Date: Thu, 23 Jan 2025 17:01:18 +0000 Subject: [PATCH 1/6] Search delegate now can have many sources --- ...odel.kt => BLESearchConnectionDelegate.kt} | 20 ++++++++++++---- .../search/ConnectionSearchDelegate.kt | 14 +++++++++++ .../search/ConnectionSearchViewModel.kt | 19 ++++++++++++--- ...earchViewModel.kt => USBSearchDelegate.kt} | 23 +++++++++++++------ 4 files changed, 61 insertions(+), 15 deletions(-) rename components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/{BLESearchViewModel.kt => BLESearchConnectionDelegate.kt} (81%) create mode 100644 components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDelegate.kt rename components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/{USBSearchViewModel.kt => USBSearchDelegate.kt} (81%) diff --git a/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchViewModel.kt b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchConnectionDelegate.kt similarity index 81% rename from components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchViewModel.kt rename to components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchConnectionDelegate.kt index 216c8836be..20adc0caaa 100644 --- a/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchViewModel.kt +++ b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchConnectionDelegate.kt @@ -7,29 +7,33 @@ import com.flipperdevices.bridge.connection.config.api.FDevicePersistedStorage import com.flipperdevices.bridge.connection.config.api.model.FDeviceFlipperZeroBleModel import com.flipperdevices.core.di.AppGraph import com.flipperdevices.core.preference.pb.FlipperZeroBle -import com.squareup.anvil.annotations.ContributesBinding +import com.squareup.anvil.annotations.ContributesMultibinding +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import me.gulya.anvil.assisted.ContributesAssistedFactory import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.kotlin.ble.core.scanner.BleScanMode import no.nordicsemi.android.kotlin.ble.core.scanner.BleScannerSettings import no.nordicsemi.android.kotlin.ble.scanner.BleScanner import no.nordicsemi.android.kotlin.ble.scanner.aggregator.BleScanResultAggregator -import javax.inject.Inject @SuppressLint("MissingPermission") -@ContributesBinding(AppGraph::class, ConnectionSearchViewModel::class) -class BLESearchViewModel @Inject constructor( +class BLESearchConnectionDelegate @AssistedInject constructor( + @Assisted viewModelScope: CoroutineScope, context: Context, persistedStorage: FDevicePersistedStorage -) : ConnectionSearchViewModel(persistedStorage) { +) : ConnectionSearchDelegate { private val aggregator = BleScanResultAggregator() private val devicesFlow = MutableStateFlow>( persistentListOf() @@ -62,6 +66,12 @@ class BLESearchViewModel @Inject constructor( } override fun getDevicesFlow() = devicesFlow.asStateFlow() + + @AssistedFactory + @ContributesMultibinding(AppGraph::class, ConnectionSearchDelegate.Factory::class) + fun interface Factory : ConnectionSearchDelegate.Factory { + override fun invoke(scope: CoroutineScope): BLESearchConnectionDelegate + } } private fun ServerDevice.toFDeviceFlipperZeroBleModel() = FDeviceFlipperZeroBleModel( diff --git a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDelegate.kt b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDelegate.kt new file mode 100644 index 0000000000..d547eebcbc --- /dev/null +++ b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDelegate.kt @@ -0,0 +1,14 @@ +package com.flipperdevices.bridge.connection.screens.search + +import kotlinx.collections.immutable.ImmutableList +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.StateFlow + +interface ConnectionSearchDelegate { + fun getDevicesFlow(): StateFlow> + fun interface Factory { + operator fun invoke( + scope: CoroutineScope, + ): ConnectionSearchDelegate + } +} \ No newline at end of file diff --git a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchViewModel.kt b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchViewModel.kt index 86347267ac..c50c203757 100644 --- a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchViewModel.kt +++ b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchViewModel.kt @@ -3,13 +3,26 @@ package com.flipperdevices.bridge.connection.screens.search import com.flipperdevices.bridge.connection.config.api.FDevicePersistedStorage import com.flipperdevices.core.ui.lifecycle.DecomposeViewModel import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch +import javax.inject.Inject -abstract class ConnectionSearchViewModel( - private val persistedStorage: FDevicePersistedStorage +class ConnectionSearchViewModel @Inject constructor( + private val persistedStorage: FDevicePersistedStorage, + searchDelegatesFactories: MutableSet ) : DecomposeViewModel() { - abstract fun getDevicesFlow(): StateFlow> + private val searchDelegates = searchDelegatesFactories.map { it(viewModelScope) } + private val combinedFlow = combine(searchDelegates.map { it.getDevicesFlow() }) { flows -> + flows.toList().flatten().toImmutableList() + }.stateIn(viewModelScope, SharingStarted.Lazily, persistentListOf()) + + fun getDevicesFlow() = combinedFlow + fun onDeviceClick(searchItem: ConnectionSearchItem) { viewModelScope.launch { if (searchItem.isAdded) { diff --git a/components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchViewModel.kt b/components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt similarity index 81% rename from components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchViewModel.kt rename to components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt index 68dc2443a2..9354ac3ba4 100644 --- a/components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchViewModel.kt +++ b/components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt @@ -6,25 +6,27 @@ import com.flipperdevices.bridge.connection.config.api.model.FDeviceFlipperZeroU import com.flipperdevices.core.di.AppGraph import com.flipperdevices.core.log.LogTagProvider import com.flipperdevices.core.log.info -import com.squareup.anvil.annotations.ContributesBinding +import com.squareup.anvil.annotations.ContributesMultibinding +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.delay +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flow import kotlinx.coroutines.launch -import javax.inject.Inject import kotlin.time.Duration.Companion.seconds private val FLIPPER_NAME_REGEXP = "Flipper ([A-Za-z]+)".toRegex() -@ContributesBinding(AppGraph::class, ConnectionSearchViewModel::class) -class USBSearchViewModel @Inject constructor( +class USBSearchDelegate @AssistedInject constructor( + @Assisted viewModelScope: CoroutineScope, private val persistedStorage: FDevicePersistedStorage -) : ConnectionSearchViewModel(persistedStorage), LogTagProvider { +) : ConnectionSearchDelegate, LogTagProvider { override val TAG = "USBSearchViewModel" private val searchItems = @@ -36,7 +38,7 @@ class USBSearchViewModel @Inject constructor( flow { while (true) { emit(Unit) - delay(1.seconds) + kotlinx.coroutines.delay(1.seconds) } }, persistedStorage.getAllDevices() @@ -69,6 +71,13 @@ class USBSearchViewModel @Inject constructor( } override fun getDevicesFlow() = searchItems.asStateFlow() + + + @AssistedFactory + @ContributesMultibinding(AppGraph::class, ConnectionSearchDelegate.Factory::class) + fun interface Factory : ConnectionSearchDelegate.Factory { + override fun invoke(scope: CoroutineScope): USBSearchDelegate + } } private fun SerialPort.toFDeviceFlipperZeroUSBModel(): FDeviceFlipperZeroUsbModel { From 80c720f8e28843ca812b50b79259b901d7b3def8 Mon Sep 17 00:00:00 2001 From: Nikita Kulikov Date: Thu, 23 Jan 2025 17:21:31 +0000 Subject: [PATCH 2/6] Add search usb --- .../connection/sample/shared/build.gradle.kts | 1 + .../screens/search/USBSearchDelegate.kt | 102 ++++++++++++++++++ gradle/libs.versions.toml | 4 +- 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt diff --git a/components/bridge/connection/sample/shared/build.gradle.kts b/components/bridge/connection/sample/shared/build.gradle.kts index 23aa59996c..d5f58a1a08 100644 --- a/components/bridge/connection/sample/shared/build.gradle.kts +++ b/components/bridge/connection/sample/shared/build.gradle.kts @@ -133,4 +133,5 @@ androidDependencies { api(libs.ble.kotlin.client) api(libs.compose.activity) + implementation(libs.usb.android) } diff --git a/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt new file mode 100644 index 0000000000..15b6b17125 --- /dev/null +++ b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt @@ -0,0 +1,102 @@ +package com.flipperdevices.bridge.connection.screens.search + +import android.content.Context +import android.hardware.usb.UsbDevice +import android.hardware.usb.UsbManager +import com.flipperdevices.bridge.connection.config.api.FDevicePersistedStorage +import com.flipperdevices.bridge.connection.config.api.model.FDeviceFlipperZeroUsbModel +import com.flipperdevices.core.di.AppGraph +import com.flipperdevices.core.log.LogTagProvider +import com.flipperdevices.core.log.info +import com.hoho.android.usbserial.driver.UsbSerialProber +import com.squareup.anvil.annotations.ContributesMultibinding +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.launch +import kotlin.time.Duration.Companion.seconds + +private val FLIPPER_NAME_REGEXP = "Flipper ([A-Za-z]+)".toRegex() + +class USBSearchDelegate @AssistedInject constructor( + @Assisted viewModelScope: CoroutineScope, + private val context: Context, + private val persistedStorage: FDevicePersistedStorage +) : ConnectionSearchDelegate, LogTagProvider { + override val TAG = "USBSearchViewModel" + + private val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager + + private val searchItems = + MutableStateFlow>(persistentListOf()) + + init { + viewModelScope.launch { + combine( + flow { + while (true) { + emit(Unit) + kotlinx.coroutines.delay(1.seconds) + } + }, + persistedStorage.getAllDevices() + ) { _, savedDevices -> + UsbSerialProber + .getDefaultProber() + .findAllDrivers(usbManager) + .map { it.device } to savedDevices + }.collect { (searchDevices, savedDevices) -> + val existedDescriptors = savedDevices + .filterIsInstance() + .associateBy { it.portPath } + + info { searchDevices.joinToString(",") { "${it}" } } + + searchItems.emit( + searchDevices.map { it.toFDeviceFlipperZeroUSBModel() }.map { usbDevice -> + ConnectionSearchItem( + address = usbDevice.portPath, + deviceModel = existedDescriptors[usbDevice.portPath] + ?: usbDevice, + isAdded = existedDescriptors.containsKey(usbDevice.portPath) + ) + }.distinctBy { it.address } + .toImmutableList() + + ) + } + } + } + + override fun getDevicesFlow() = searchItems.asStateFlow() + + + @AssistedFactory + @ContributesMultibinding(AppGraph::class, ConnectionSearchDelegate.Factory::class) + fun interface Factory : ConnectionSearchDelegate.Factory { + override fun invoke(scope: CoroutineScope): USBSearchDelegate + } +} + +private fun UsbDevice.toFDeviceFlipperZeroUSBModel(): FDeviceFlipperZeroUsbModel { + return FDeviceFlipperZeroUsbModel( + name = productName?.extractFlipperName() ?: deviceName, + portPath = deviceName, + humanReadableName = deviceName, + ) +} + +private fun String.extractFlipperName(): String { + val regexFind = FLIPPER_NAME_REGEXP.find(this) + val groups = regexFind?.groupValues + return groups?.getOrNull(index = 1) + ?: this +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0f59a402bc..e24456b010 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -100,8 +100,9 @@ buildkonfig = "5.5.1" wire = "5.1.0" okio = "3.9.1" -jserial = "2.11.0" +jserial = "2.11.0" +usb-android = "3.8.1" [libraries] # Gradle - Core @@ -248,6 +249,7 @@ ble-kotlin-client = { module = "no.nordicsemi.android.kotlin.ble:client", versio # USB jserial = { module = "com.fazecast:jSerialComm", version.ref = "jserial" } +usb-android = { module = "com.github.mik3y:usb-serial-for-android", version.ref = "usb-android" } # Images image-lottie = { module = "com.airbnb.android:lottie-compose", version.ref = "lottie" } From 71889d4b59998e31e0b371ad2869d5bc0ab42912 Mon Sep 17 00:00:00 2001 From: Nikita Kulikov Date: Thu, 23 Jan 2025 22:18:39 +0000 Subject: [PATCH 3/6] Base implementation of USB serial --- .../sample/android/build.gradle.kts | 1 + .../connection/ConnectionTestApplication.kt | 3 + .../connection/sample/shared/build.gradle.kts | 5 + .../screens/search/USBSearchDelegate.kt | 4 +- .../drawable/material_ic_bluetooth.xml | 9 ++ .../drawable/material_ic_usb.xml | 9 ++ .../ConnectionSearchDecomposeComponent.kt | 17 ++ .../screens/search/ConnectionSearchItem.kt | 2 +- .../transport/usb/impl/build.gradle.kts | 9 +- .../usb/impl/model/USBAndroidDevice.kt | 90 +++++++++++ .../usb/impl/model/USBAndroidDeviceFactory.kt | 36 +++++ .../usb/impl/model/USBSerialListener.kt | 74 +++++++++ .../usb/impl/model/USBDesktopDevice.kt | 34 ++++ .../usb/impl/model/USBDesktopDeviceFactory.kt | 18 +++ .../usb/impl/USBDeviceConnectionApiImpl.kt | 20 ++- .../usb/impl/di/BleDeviceConnectionModule.kt | 10 +- .../usb/impl/model/USBPlatformDevice.kt | 26 +++ .../impl/model/USBPlatformDeviceFactory.kt | 11 ++ .../usb/impl/serial/FUSBSerialDeviceApi.kt | 6 +- components/bridge/pbutils/src/main/proto | 1 - .../pbutils/src/main/proto/.github/CODEOWNERS | 3 + .../main/proto/.github/workflows/generate.yml | 30 ++++ .../bridge/pbutils/src/main/proto/.gitignore | 8 + .../bridge/pbutils/src/main/proto/Changelog | 105 ++++++++++++ .../src/main/proto/application.options | 8 + .../pbutils/src/main/proto/application.proto | 58 +++++++ .../pbutils/src/main/proto/desktop.proto | 20 +++ .../pbutils/src/main/proto/flipper.options | 6 + .../pbutils/src/main/proto/flipper.proto | 151 ++++++++++++++++++ .../pbutils/src/main/proto/gpio.options | 0 .../bridge/pbutils/src/main/proto/gpio.proto | 73 +++++++++ .../bridge/pbutils/src/main/proto/gui.options | 2 + .../bridge/pbutils/src/main/proto/gui.proto | 52 ++++++ .../pbutils/src/main/proto/property.options | 3 + .../pbutils/src/main/proto/property.proto | 13 ++ .../pbutils/src/main/proto/storage.options | 26 +++ .../pbutils/src/main/proto/storage.proto | 99 ++++++++++++ .../pbutils/src/main/proto/system.options | 16 ++ .../pbutils/src/main/proto/system.proto | 95 +++++++++++ 39 files changed, 1133 insertions(+), 20 deletions(-) create mode 100644 components/bridge/connection/sample/shared/src/commonMain/composeResources/drawable/material_ic_bluetooth.xml create mode 100644 components/bridge/connection/sample/shared/src/commonMain/composeResources/drawable/material_ic_usb.xml create mode 100644 components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDevice.kt create mode 100644 components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDeviceFactory.kt create mode 100644 components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBSerialListener.kt create mode 100644 components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDevice.kt create mode 100644 components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDeviceFactory.kt create mode 100644 components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDevice.kt create mode 100644 components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDeviceFactory.kt delete mode 160000 components/bridge/pbutils/src/main/proto create mode 100644 components/bridge/pbutils/src/main/proto/.github/CODEOWNERS create mode 100644 components/bridge/pbutils/src/main/proto/.github/workflows/generate.yml create mode 100644 components/bridge/pbutils/src/main/proto/.gitignore create mode 100644 components/bridge/pbutils/src/main/proto/Changelog create mode 100644 components/bridge/pbutils/src/main/proto/application.options create mode 100644 components/bridge/pbutils/src/main/proto/application.proto create mode 100644 components/bridge/pbutils/src/main/proto/desktop.proto create mode 100644 components/bridge/pbutils/src/main/proto/flipper.options create mode 100644 components/bridge/pbutils/src/main/proto/flipper.proto create mode 100644 components/bridge/pbutils/src/main/proto/gpio.options create mode 100644 components/bridge/pbutils/src/main/proto/gpio.proto create mode 100644 components/bridge/pbutils/src/main/proto/gui.options create mode 100644 components/bridge/pbutils/src/main/proto/gui.proto create mode 100644 components/bridge/pbutils/src/main/proto/property.options create mode 100644 components/bridge/pbutils/src/main/proto/property.proto create mode 100644 components/bridge/pbutils/src/main/proto/storage.options create mode 100644 components/bridge/pbutils/src/main/proto/storage.proto create mode 100644 components/bridge/pbutils/src/main/proto/system.options create mode 100644 components/bridge/pbutils/src/main/proto/system.proto diff --git a/components/bridge/connection/sample/android/build.gradle.kts b/components/bridge/connection/sample/android/build.gradle.kts index e76cdf6766..8847caa970 100644 --- a/components/bridge/connection/sample/android/build.gradle.kts +++ b/components/bridge/connection/sample/android/build.gradle.kts @@ -20,6 +20,7 @@ commonDependencies { androidDependencies { implementation(projects.components.core.di) + implementation(projects.components.core.activityholder) } dependencies { diff --git a/components/bridge/connection/sample/android/src/androidMain/kotlin/com/flipperdevices/bridge/connection/ConnectionTestApplication.kt b/components/bridge/connection/sample/android/src/androidMain/kotlin/com/flipperdevices/bridge/connection/ConnectionTestApplication.kt index b639086e88..cde6615fd2 100644 --- a/components/bridge/connection/sample/android/src/androidMain/kotlin/com/flipperdevices/bridge/connection/ConnectionTestApplication.kt +++ b/components/bridge/connection/sample/android/src/androidMain/kotlin/com/flipperdevices/bridge/connection/ConnectionTestApplication.kt @@ -3,6 +3,7 @@ package com.flipperdevices.bridge.connection import android.app.Application import com.flipperdevices.bridge.connection.di.AppComponent import com.flipperdevices.bridge.connection.di.DaggerMergedAndroidAppComponent +import com.flipperdevices.core.activityholder.CurrentActivityHolder import com.flipperdevices.core.di.ApplicationParams import com.flipperdevices.core.di.ComponentHolder import timber.log.Timber @@ -27,5 +28,7 @@ class ConnectionTestApplication : Application() { ComponentHolder.components += appComponent Timber.plant(Timber.DebugTree()) + + CurrentActivityHolder.register(this) } } diff --git a/components/bridge/connection/sample/shared/build.gradle.kts b/components/bridge/connection/sample/shared/build.gradle.kts index d5f58a1a08..63db20a19e 100644 --- a/components/bridge/connection/sample/shared/build.gradle.kts +++ b/components/bridge/connection/sample/shared/build.gradle.kts @@ -72,6 +72,8 @@ commonDependencies { api(projects.components.bridge.connection.feature.screenstreaming.impl) api(projects.components.bridge.connection.feature.update.api) api(projects.components.bridge.connection.feature.update.impl) + api(projects.components.bridge.connection.feature.emulate.api) + api(projects.components.bridge.connection.feature.emulate.impl) api(projects.components.filemngr.main.api) api(projects.components.filemngr.main.impl) @@ -117,6 +119,9 @@ androidDependencies { api(projects.components.bridge.connection.transport.ble.api) api(projects.components.bridge.connection.transport.ble.impl) + api(projects.components.bridge.connection.transport.usb.api) + api(projects.components.bridge.connection.transport.usb.impl) + api(projects.components.firstpair.connection.api) api(projects.components.keyparser.api) diff --git a/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt index 15b6b17125..436168a9c6 100644 --- a/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt +++ b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt @@ -89,8 +89,8 @@ class USBSearchDelegate @AssistedInject constructor( private fun UsbDevice.toFDeviceFlipperZeroUSBModel(): FDeviceFlipperZeroUsbModel { return FDeviceFlipperZeroUsbModel( name = productName?.extractFlipperName() ?: deviceName, - portPath = deviceName, - humanReadableName = deviceName, + portPath = deviceId.toString(), + humanReadableName = productName ?: deviceName, ) } diff --git a/components/bridge/connection/sample/shared/src/commonMain/composeResources/drawable/material_ic_bluetooth.xml b/components/bridge/connection/sample/shared/src/commonMain/composeResources/drawable/material_ic_bluetooth.xml new file mode 100644 index 0000000000..65a1155542 --- /dev/null +++ b/components/bridge/connection/sample/shared/src/commonMain/composeResources/drawable/material_ic_bluetooth.xml @@ -0,0 +1,9 @@ + + + diff --git a/components/bridge/connection/sample/shared/src/commonMain/composeResources/drawable/material_ic_usb.xml b/components/bridge/connection/sample/shared/src/commonMain/composeResources/drawable/material_ic_usb.xml new file mode 100644 index 0000000000..5ac270e279 --- /dev/null +++ b/components/bridge/connection/sample/shared/src/commonMain/composeResources/drawable/material_ic_usb.xml @@ -0,0 +1,9 @@ + + + diff --git a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDecomposeComponent.kt b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDecomposeComponent.kt index 9667f41277..330a146067 100644 --- a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDecomposeComponent.kt +++ b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDecomposeComponent.kt @@ -32,6 +32,9 @@ import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import javax.inject.Provider import flipperapp.components.core.ui.res.generated.resources.Res as SharedRes +import com.flipperdevices.bridge.connection.config.api.FDeviceType +import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_bluetooth +import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_usb class ConnectionSearchDecomposeComponent @AssistedInject constructor( @Assisted componentContext: ComponentContext, @@ -69,6 +72,20 @@ class ConnectionSearchDecomposeComponent @AssistedInject constructor( key = { device -> device.address } ) { searchItem -> Row { + Icon( + modifier = Modifier + .padding(16.dp) + .size(24.dp), + painter = painterResource( + when(searchItem.deviceModel.type) { + FDeviceType.FLIPPER_ZERO_BLE -> Res.drawable.material_ic_bluetooth + FDeviceType.FLIPPER_ZERO_USB -> Res.drawable.material_ic_usb + } + ), + contentDescription = null, + tint = LocalPallet.current.text100 + ) + Text( modifier = Modifier .weight(1f) diff --git a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItem.kt b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItem.kt index 73ca96e4e2..b8bacce30c 100644 --- a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItem.kt +++ b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItem.kt @@ -6,4 +6,4 @@ data class ConnectionSearchItem( val address: String, val deviceModel: FDeviceBaseModel, val isAdded: Boolean -) +) \ No newline at end of file diff --git a/components/bridge/connection/transport/usb/impl/build.gradle.kts b/components/bridge/connection/transport/usb/impl/build.gradle.kts index 0968b876b9..1cede1d956 100644 --- a/components/bridge/connection/transport/usb/impl/build.gradle.kts +++ b/components/bridge/connection/transport/usb/impl/build.gradle.kts @@ -21,6 +21,13 @@ commonDependencies { implementation(libs.kotlin.coroutines) } -jvmSharedDependencies { +desktopDependencies { implementation(libs.jserial) } + +androidDependencies { + implementation(projects.components.core.activityholder) + + implementation(libs.fastutil) + implementation(libs.usb.android) +} diff --git a/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDevice.kt b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDevice.kt new file mode 100644 index 0000000000..bbb1ab27a1 --- /dev/null +++ b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDevice.kt @@ -0,0 +1,90 @@ +package com.flipperdevices.bridge.connection.transport.usb.impl.model + +import android.app.PendingIntent +import android.content.Intent +import android.hardware.usb.UsbManager +import android.util.Log +import com.flipperdevices.core.activityholder.CurrentActivityHolder +import com.flipperdevices.core.log.LogTagProvider +import com.flipperdevices.core.log.error +import com.hoho.android.usbserial.driver.UsbSerialDriver +import com.hoho.android.usbserial.util.SerialInputOutputManager +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +private const val RW_TIMEOUT = 0 + +class USBAndroidDevice( + private val serialDriver: UsbSerialDriver, + private val usbManager: UsbManager, + private val scope: CoroutineScope +) : USBPlatformDevice, LogTagProvider { + override val TAG = "USBAndroidDevice" + + private val serialPort = serialDriver.ports.first() + private val serialListener = USBSerialListener(scope) + + override fun connect(baudRate: Int, dataBits: Int, stopBits: Int, parity: Int): Boolean { + val connection = runCatching { usbManager.openDevice(serialPort.device) } + .onFailure { error(it) { "Fail open connection" } } + .getOrNull() + if (connection == null) { + requestPermission() + error("Connection is null, request permission") + } + + serialPort.open(connection) + serialPort.setParameters(baudRate, dataBits, stopBits, parity) + serialPort.dtr = true + serialPort.rts = true + + val ioManager = SerialInputOutputManager(serialPort, serialListener) + scope.launch { + try { + awaitCancellation() + } finally { + withContext(NonCancellable) { + ioManager.stop() + } + } + } + ioManager.start() + return true + } + + private fun requestPermission() { + if (!usbManager.hasPermission(serialDriver.device)) { + + val intent = Intent("Test") + + val activity = CurrentActivityHolder.getCurrentActivity() + ?: error("Failed get current activity") + intent.setPackage(activity.packageName) + val usbPermissionIntent = + PendingIntent.getBroadcast(activity, 0, intent, PendingIntent.FLAG_MUTABLE) + usbManager.requestPermission(serialDriver.device, usbPermissionIntent) + return + } + } + + override fun closePort() { + serialPort.close() + } + + override fun writeBytes(buffer: ByteArray, bytesToWrite: Int, offset: Int): Int { + val subBuffer = if (offset == 0) { + buffer + } else { + buffer.copyOfRange(offset, buffer.size) + } + serialPort.write(subBuffer, bytesToWrite, RW_TIMEOUT) + return bytesToWrite + } + + override fun readBytes(buffer: ByteArray, bytesToRead: Int): Int { + return serialListener.readBytes(buffer, bytesToRead) + } +} diff --git a/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDeviceFactory.kt b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDeviceFactory.kt new file mode 100644 index 0000000000..ed20fb3183 --- /dev/null +++ b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDeviceFactory.kt @@ -0,0 +1,36 @@ +package com.flipperdevices.bridge.connection.transport.usb.impl.model + +import android.content.Context +import android.hardware.usb.UsbManager +import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig +import com.flipperdevices.core.di.AppGraph +import com.hoho.android.usbserial.driver.UsbSerialProber +import com.squareup.anvil.annotations.ContributesBinding +import kotlinx.coroutines.CoroutineScope +import javax.inject.Inject + + +@ContributesBinding(AppGraph::class, USBPlatformDeviceFactory::class) +class USBAndroidDeviceFactory @Inject constructor( + private val context: Context +) : USBPlatformDeviceFactory { + override fun getUSBPlatformDevice( + config: FUSBDeviceConnectionConfig, + scope: CoroutineScope + ): USBPlatformDevice { + val manager = context.getSystemService(Context.USB_SERVICE) as UsbManager + val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager) + val device = availableDrivers.filter { + it.device.deviceId.toString() == config.path + }.firstOrNull() + if (device == null) { + error("Failed find device with id ${config.path}") + } + + return USBAndroidDevice( + serialDriver = device, + usbManager = manager, + scope = scope + ) + } +} \ No newline at end of file diff --git a/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBSerialListener.kt b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBSerialListener.kt new file mode 100644 index 0000000000..e629b88733 --- /dev/null +++ b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBSerialListener.kt @@ -0,0 +1,74 @@ +package com.flipperdevices.bridge.connection.transport.usb.impl.model + +import com.flipperdevices.core.log.LogTagProvider +import com.flipperdevices.core.log.error +import com.flipperdevices.core.log.info +import com.hoho.android.usbserial.util.SerialInputOutputManager +import it.unimi.dsi.fastutil.bytes.ByteArrayFIFOQueue +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class USBSerialListener( + scope: CoroutineScope +) : SerialInputOutputManager.Listener, LogTagProvider { + override val TAG = "USBSerialListener" + + private val queue = ByteArrayFIFOQueue() + + init { + scope.launch { + try { + awaitCancellation() + } finally { + withContext(NonCancellable) { + synchronized(queue) { + queue.notifyAll() + } + } + } + } + } + + fun readBytes( + buffer: ByteArray, + bytesToRead: Int + ): Int { + var index = 0 + synchronized(queue) { + while (queue.isEmpty) { + queue.wait() + } + while (index < bytesToRead && !queue.isEmpty) { + buffer[index++] = queue.dequeueByte() + } + } + return index + } + + override fun onNewData(data: ByteArray?) { + info { "Receive $data" } + synchronized(queue) { + data?.forEach { + queue.enqueue(it) + } + queue.notifyAll() + } + } + + override fun onRunError(e: Exception?) { + error(e) { "Failed in usb serial" } + } +} + +@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") +private fun Any.wait() { + (this as Object).wait() +} + +@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") +private fun Any.notifyAll() { + (this as Object).notifyAll() +} \ No newline at end of file diff --git a/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDevice.kt b/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDevice.kt new file mode 100644 index 0000000000..f1c8d351fc --- /dev/null +++ b/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDevice.kt @@ -0,0 +1,34 @@ +package com.flipperdevices.bridge.connection.transport.usb.impl.model + +import com.fazecast.jSerialComm.SerialPort +import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig + +private const val OPEN_PORT_TIME_MS = 1000 + +class USBDesktopDevice( + private val serialPort: SerialPort +) : USBPlatformDevice { + override fun connect(baudRate: Int, dataBits: Int, stopBits: Int, parity: Int): Boolean { + serialPort.setComPortParameters( + baudRate, + dataBits, + SerialPort.ONE_STOP_BIT, + SerialPort.NO_PARITY + ) + serialPort.openPort(OPEN_PORT_TIME_MS) + serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0) + return serialPort.openPort() + } + + override fun closePort() { + serialPort.closePort() + } + + override fun writeBytes(buffer: ByteArray, bytesToWrite: Int, offset: Int): Int { + return serialPort.writeBytes(buffer, bytesToWrite, offset) + } + + override fun readBytes(buffer: ByteArray, bytesToRead: Int): Int { + return serialPort.readBytes(buffer, bytesToRead) + } +} diff --git a/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDeviceFactory.kt b/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDeviceFactory.kt new file mode 100644 index 0000000000..662eba66cf --- /dev/null +++ b/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDeviceFactory.kt @@ -0,0 +1,18 @@ +package com.flipperdevices.bridge.connection.transport.usb.impl.model + +import com.fazecast.jSerialComm.SerialPort +import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig +import com.flipperdevices.core.di.AppGraph +import com.squareup.anvil.annotations.ContributesBinding +import kotlinx.coroutines.CoroutineScope +import javax.inject.Inject + +@ContributesBinding(AppGraph::class, USBPlatformDeviceFactory::class) +class USBDesktopDeviceFactory @Inject constructor() : USBPlatformDeviceFactory { + override fun getUSBPlatformDevice( + config: FUSBDeviceConnectionConfig, + scope: CoroutineScope + ): USBPlatformDevice { + return USBDesktopDevice(SerialPort.getCommPort(config.path)) + } +} \ No newline at end of file diff --git a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/USBDeviceConnectionApiImpl.kt b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/USBDeviceConnectionApiImpl.kt index e3c8fc4228..86184b34b3 100644 --- a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/USBDeviceConnectionApiImpl.kt +++ b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/USBDeviceConnectionApiImpl.kt @@ -1,12 +1,13 @@ package com.flipperdevices.bridge.connection.transport.usb.impl -import com.fazecast.jSerialComm.SerialPort import com.flipperdevices.bridge.connection.feature.actionnotifier.api.FlipperActionNotifier import com.flipperdevices.bridge.connection.transport.common.api.FInternalTransportConnectionStatus import com.flipperdevices.bridge.connection.transport.common.api.FTransportConnectionStatusListener import com.flipperdevices.bridge.connection.transport.usb.api.FUSBApi import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig import com.flipperdevices.bridge.connection.transport.usb.api.USBDeviceConnectionApi +import com.flipperdevices.bridge.connection.transport.usb.impl.model.USBPlatformDevice +import com.flipperdevices.bridge.connection.transport.usb.impl.model.USBPlatformDeviceFactory import com.flipperdevices.bridge.connection.transport.usb.impl.serial.FUSBSerialDeviceApi import com.flipperdevices.core.log.LogTagProvider import com.flipperdevices.core.log.info @@ -20,10 +21,10 @@ private val FLOOD_END_STRING = "\r\n\r\n>: ".toByteArray() private val COMMAND = "start_rpc_session\r".toByteArray() private const val BAUD_RATE = 230400 private const val DATA_BITS = 8 -private const val OPEN_PORT_TIME_MS = 1000 class USBDeviceConnectionApiImpl( - private val actionNotifierFactory: FlipperActionNotifier.Factory + private val actionNotifierFactory: FlipperActionNotifier.Factory, + private val usbPlatformDeviceFactory: USBPlatformDeviceFactory ) : USBDeviceConnectionApi, LogTagProvider { override val TAG = "USBDeviceConnectionApi" @@ -33,16 +34,13 @@ class USBDeviceConnectionApiImpl( listener: FTransportConnectionStatusListener ): Result = runCatching { listener.onStatusUpdate(FInternalTransportConnectionStatus.Connecting) - val serialPort = SerialPort.getCommPort(config.path) - serialPort.setComPortParameters( + val serialPort = usbPlatformDeviceFactory.getUSBPlatformDevice(config, scope) + val portOpened = serialPort.connect( BAUD_RATE, DATA_BITS, - SerialPort.ONE_STOP_BIT, - SerialPort.NO_PARITY + USBPlatformDevice.ONE_STOP_BIT, + USBPlatformDevice.NO_PARITY ) - serialPort.openPort(OPEN_PORT_TIME_MS) - serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0) - val portOpened = serialPort.openPort() info { "Read port is: $portOpened" } @@ -80,7 +78,7 @@ class USBDeviceConnectionApiImpl( } @OptIn(ExperimentalStdlibApi::class) - private fun skipFlood(serialPort: SerialPort, floodBytes: ByteArray) { + private fun skipFlood(serialPort: USBPlatformDevice, floodBytes: ByteArray) { info { "Start wait flood" } var floodCurrentIndex = 0 val buffer = ByteArray(size = 1) diff --git a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/di/BleDeviceConnectionModule.kt b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/di/BleDeviceConnectionModule.kt index 049e6e18c9..4cbf56cc13 100644 --- a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/di/BleDeviceConnectionModule.kt +++ b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/di/BleDeviceConnectionModule.kt @@ -5,6 +5,8 @@ import com.flipperdevices.bridge.connection.transport.common.api.di.DeviceConnec import com.flipperdevices.bridge.connection.transport.common.api.di.toHolder import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig import com.flipperdevices.bridge.connection.transport.usb.impl.USBDeviceConnectionApiImpl +import com.flipperdevices.bridge.connection.transport.usb.impl.model.USBPlatformDevice +import com.flipperdevices.bridge.connection.transport.usb.impl.model.USBPlatformDeviceFactory import com.flipperdevices.core.di.AppGraph import com.squareup.anvil.annotations.ContributesTo import dagger.Module @@ -20,6 +22,10 @@ class BleDeviceConnectionModule { @IntoMap @ClassKey(FUSBDeviceConnectionConfig::class) fun provideBleDeviceConnectionApi( - actionNotifierFactory: FlipperActionNotifier.Factory - ): DeviceConnectionApiHolder = USBDeviceConnectionApiImpl(actionNotifierFactory).toHolder() + actionNotifierFactory: FlipperActionNotifier.Factory, + platformDeviceFactory: USBPlatformDeviceFactory + ): DeviceConnectionApiHolder = USBDeviceConnectionApiImpl( + actionNotifierFactory, + platformDeviceFactory + ).toHolder() } diff --git a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDevice.kt b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDevice.kt new file mode 100644 index 0000000000..e9b8db8cee --- /dev/null +++ b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDevice.kt @@ -0,0 +1,26 @@ +package com.flipperdevices.bridge.connection.transport.usb.impl.model + +import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig + +interface USBPlatformDevice { + fun connect(baudRate: Int, dataBits: Int, stopBits: Int, parity: Int): Boolean + fun closePort() + + fun writeBytes(buffer: ByteArray, bytesToWrite: Int = buffer.size, offset: Int = 0): Int + + fun readBytes(buffer: ByteArray, bytesToRead: Int = buffer.size): Int + + companion object { + // Parity Values + const val NO_PARITY: Int = 0 + const val ODD_PARITY: Int = 1 + const val EVEN_PARITY: Int = 2 + const val MARK_PARITY: Int = 3 + const val SPACE_PARITY: Int = 4 + + // Number of Stop Bits + const val ONE_STOP_BIT: Int = 1 + const val ONE_POINT_FIVE_STOP_BITS: Int = 2 + const val TWO_STOP_BITS: Int = 3 + } +} \ No newline at end of file diff --git a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDeviceFactory.kt b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDeviceFactory.kt new file mode 100644 index 0000000000..75037b37aa --- /dev/null +++ b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDeviceFactory.kt @@ -0,0 +1,11 @@ +package com.flipperdevices.bridge.connection.transport.usb.impl.model + +import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig +import kotlinx.coroutines.CoroutineScope + +interface USBPlatformDeviceFactory { + fun getUSBPlatformDevice( + config: FUSBDeviceConnectionConfig, + scope: CoroutineScope + ): USBPlatformDevice +} \ No newline at end of file diff --git a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/serial/FUSBSerialDeviceApi.kt b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/serial/FUSBSerialDeviceApi.kt index e97910e368..fe93fbaf16 100644 --- a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/serial/FUSBSerialDeviceApi.kt +++ b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/serial/FUSBSerialDeviceApi.kt @@ -1,12 +1,12 @@ package com.flipperdevices.bridge.connection.transport.usb.impl.serial -import com.fazecast.jSerialComm.SerialPort import com.flipperdevices.bridge.connection.feature.actionnotifier.api.FlipperActionNotifier import com.flipperdevices.bridge.connection.transport.common.api.meta.FTransportMetaInfoApi import com.flipperdevices.bridge.connection.transport.common.api.serial.FSerialDeviceApi import com.flipperdevices.bridge.connection.transport.common.api.serial.FSerialRestartApi import com.flipperdevices.bridge.connection.transport.common.api.serial.FlipperSerialSpeed import com.flipperdevices.bridge.connection.transport.usb.api.FUSBApi +import com.flipperdevices.bridge.connection.transport.usb.impl.model.USBPlatformDevice import com.flipperdevices.core.log.LogTagProvider import com.flipperdevices.core.log.info import kotlinx.coroutines.CoroutineScope @@ -19,7 +19,7 @@ import kotlinx.coroutines.launch class FUSBSerialDeviceApi( private val scope: CoroutineScope, - private val serialPort: SerialPort, + private val serialPort: USBPlatformDevice, private val actionNotifier: FlipperActionNotifier ) : FUSBApi, FSerialDeviceApi, @@ -40,6 +40,7 @@ class FUSBSerialDeviceApi( while (result > 0) { result = serialPort.readBytes(buffer, buffer.size) val readBytes = buffer.take(result).toByteArray() + rxSpeed.onReceiveBytes(result) receiverByteFlow.emit(readBytes) } error("End loop with result $result") @@ -65,6 +66,7 @@ class FUSBSerialDeviceApi( val writtenBytes = serialPort.writeBytes(data, data.size - writtenBytesOffset, writtenBytesOffset) info { "Write $writtenBytes" } + txSpeed.onReceiveBytes(writtenBytes) if (writtenBytes == -1) { error("Failed to write bytes") } diff --git a/components/bridge/pbutils/src/main/proto b/components/bridge/pbutils/src/main/proto deleted file mode 160000 index ee5b6a22fd..0000000000 --- a/components/bridge/pbutils/src/main/proto +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ee5b6a22fd6aaf9075a2b7bd373309592e6627c5 diff --git a/components/bridge/pbutils/src/main/proto/.github/CODEOWNERS b/components/bridge/pbutils/src/main/proto/.github/CODEOWNERS new file mode 100644 index 0000000000..dfe56a07f4 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# Who owns all the code by default + +* @DrZlo13 @skotopes @gornekich @nminaylov @hedger diff --git a/components/bridge/pbutils/src/main/proto/.github/workflows/generate.yml b/components/bridge/pbutils/src/main/proto/.github/workflows/generate.yml new file mode 100644 index 0000000000..16d34a769c --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/.github/workflows/generate.yml @@ -0,0 +1,30 @@ +name: 'Generate protobuf sources' + +on: + push: + +jobs: + generate: + runs-on: ubuntu-latest + steps: + - name: Checkout flipperzero-protobuf + uses: actions/checkout@v2 + + - name: Checkout nanopb + uses: actions/checkout@v2 + with: + repository: nanopb/nanopb + path: nanopb + + - name: Setup python + uses: actions/setup-python@v3 + with: + python-version: '3.9' + + - name: Setup protobuf + run: | + sudo apt -y install protobuf-compiler + python3 -m pip install --upgrade python3-protobuf==2.5.0 protobuf==3.20.1 grpcio-tools==1.47.0 grpcio==1.47.0 + + - name: Generate sources + run: python3 nanopb/generator/nanopb_generator.py -q -I . -D /tmp *.proto diff --git a/components/bridge/pbutils/src/main/proto/.gitignore b/components/bridge/pbutils/src/main/proto/.gitignore new file mode 100644 index 0000000000..34165a8706 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/.gitignore @@ -0,0 +1,8 @@ +# JetBrains IDEs +.idea + +# MacOS +.DS_Store + +# Visual Studio Code +.vscode/ \ No newline at end of file diff --git a/components/bridge/pbutils/src/main/proto/Changelog b/components/bridge/pbutils/src/main/proto/Changelog new file mode 100644 index 0000000000..be5fa9c29f --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/Changelog @@ -0,0 +1,105 @@ +# Changelog + +## [0.21] +### Added +- Application AppButtonPressRequest now supports button indices in addition to names. + +## [0.20] +### Added +- Storage ListRequest message now has a file size filter. + +## [0.19] +### Added +- Storage ListRequest message now supports md5sum calculation for each file + +## [0.18] +### Added +- Loader is now able to load apps from SD card + +## [0.17] +### Added +- Desktop service subscription API + +## [0.16] +### Added +- Desktop service API + +## [0.15] +### Modified +- ScreenFrame: additional orientation field + +## [0.14] +### Added +- New subsystem: Property +- Property messages: GetRequest, GetResponse +- App messages: GetErrorRequest, GetErrorResponse, DataExchangeRequest + +## [0.13] +### Added +- Storage: timestamp + +## [0.12] +### Added +- Region message + +## [0.11] +### Added +- App messages: AppStateResponse + +## [0.10] +### Added +- GPIO message: SetPinMode, SetInputPull, GetPinMode, GetPinModeResponse, ReadPin, ReadPinResponse, WritePin + +## [0.9] +### Added +- System message: UpdateResponse, enum UpdateResultCode: new entries + OutdatedManifestVersion, IntFull, UnspecifiedError + +## [0.8] +### Added +- App messages: AppExitRequest, AppLoadFileRequest, AppButtonPressRequest, AppButtonReleaseRequest + +## [0.7] +### Added +- System message: UpdateResponse: passing update preparation detailed status + +## [0.6] +### Added +- System message: RebootRequest: added UPDATE restart mode +### Fixed +- System message: UpdateRequest: renamed manifest field + +## [0.5] +### Added +- System message: PowerInfo + +## [0.4] +### Added +- System message: UpdateRequest +- Storage messages: BackupCreateRequest, BackupRestoreRequest + +## [0.3] +### Fixed +- BLE disconnection after writing / erasing FLASH + +## [0.2] +### Added +- System messages: ProtobufVersion +- Support parallel RPC sessions +- Screen streaming optimization + +## [0.1] +### Added +- Code owners +- CI setup +- System messages: Ping, Reboot, DeviceInfo, FactoryReset, DateTime, + AudiovisualAlert +- Storage messages: Info, Stat, Read, Write, Delete, Mkdir, Md5sum, + Rename +- App messages: Start, LockStatus +- Gui messages: ScreenStream, ScreenFrame, SendInput, VirtualDisplay + +## [0.0] +### Added +- Introduced Flipper Zero Protobuf repository +- StorageList messages diff --git a/components/bridge/pbutils/src/main/proto/application.options b/components/bridge/pbutils/src/main/proto/application.options new file mode 100644 index 0000000000..338bb67d61 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/application.options @@ -0,0 +1,8 @@ +PB_App.StartRequest.args type:FT_POINTER +PB_App.StartRequest.args max_length:512 +PB_App.StartRequest.name type:FT_POINTER +PB_App.StartRequest.name max_length:512 +PB_App.AppLoadFileRequest.path max_length:512 +PB_App.AppButtonPressRequest.args max_length:512 +PB_App.GetErrorResponse.text type:FT_POINTER +PB_App.DataExchangeRequest.data type:FT_POINTER diff --git a/components/bridge/pbutils/src/main/proto/application.proto b/components/bridge/pbutils/src/main/proto/application.proto new file mode 100644 index 0000000000..4c82cdf91f --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/application.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; + +package PB_App; +option java_package = "com.flipperdevices.protobuf.app"; + +message StartRequest { + string name = 1; + string args = 2; +} + +message LockStatusRequest { +} + +message LockStatusResponse { + bool locked = 1; +} + +message AppExitRequest { +} + +message AppLoadFileRequest { + string path = 1; +} + +message AppButtonPressRequest { + string args = 1; + int32 index = 2; +} + +message AppButtonReleaseRequest { +} + +message AppButtonPressReleaseRequest { + string args = 1; + int32 index = 2; +} + +enum AppState { + APP_CLOSED = 0; + APP_STARTED = 1; +}; + +message AppStateResponse { + AppState state = 1; +} + +message GetErrorRequest { +} + +message GetErrorResponse { + uint32 code = 1; + string text = 2; +} + +message DataExchangeRequest { + bytes data = 1; +} + diff --git a/components/bridge/pbutils/src/main/proto/desktop.proto b/components/bridge/pbutils/src/main/proto/desktop.proto new file mode 100644 index 0000000000..cc8212d40c --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/desktop.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package PB_Desktop; +option java_package = "com.flipperdevices.protobuf.desktop"; + +message IsLockedRequest { +} + +message UnlockRequest { +} + +message StatusSubscribeRequest { +} + +message StatusUnsubscribeRequest { +} + +message Status { + bool locked = 1; +} diff --git a/components/bridge/pbutils/src/main/proto/flipper.options b/components/bridge/pbutils/src/main/proto/flipper.options new file mode 100644 index 0000000000..0301133444 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/flipper.options @@ -0,0 +1,6 @@ +PB.Main submsg_callback:true +PB.Region.country_code type:FT_POINTER +PB.Region.country_code max_size:2 +PB.Region.Band.power_limit int_size:IS_8 +PB.Region.Band.duty_cycle int_size:IS_8 + diff --git a/components/bridge/pbutils/src/main/proto/flipper.proto b/components/bridge/pbutils/src/main/proto/flipper.proto new file mode 100644 index 0000000000..2ba75dadce --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/flipper.proto @@ -0,0 +1,151 @@ +syntax = "proto3"; +import "storage.proto"; +import "system.proto"; +import "application.proto"; +import "gui.proto"; +import "gpio.proto"; +import "property.proto"; +import "desktop.proto"; + +package PB; +option java_package = "com.flipperdevices.protobuf"; + +enum CommandStatus { + OK = 0; + + /**< Common Errors */ + ERROR = 1; /**< Unknown error */ + ERROR_DECODE = 2; /**< Command can't be decoded successfully - command_id in response may be wrong! */ + ERROR_NOT_IMPLEMENTED = 3; /**< Command successfully decoded, but not implemented (deprecated or not yet implemented) */ + ERROR_BUSY = 4; /**< Somebody took global lock, so not all commands are available */ + ERROR_CONTINUOUS_COMMAND_INTERRUPTED = 14; /**< Not received has_next == 0 */ + ERROR_INVALID_PARAMETERS = 15; /**< not provided (or provided invalid) crucial parameters to perform RPC */ + + /**< Storage Errors */ + ERROR_STORAGE_NOT_READY = 5; /**< FS not ready */ + ERROR_STORAGE_EXIST = 6; /**< File/Dir already exist */ + ERROR_STORAGE_NOT_EXIST = 7; /**< File/Dir does not exist */ + ERROR_STORAGE_INVALID_PARAMETER = 8; /**< Invalid API parameter */ + ERROR_STORAGE_DENIED = 9; /**< Access denied */ + ERROR_STORAGE_INVALID_NAME = 10; /**< Invalid name/path */ + ERROR_STORAGE_INTERNAL = 11; /**< Internal error */ + ERROR_STORAGE_NOT_IMPLEMENTED = 12; /**< Function is not implemented */ + ERROR_STORAGE_ALREADY_OPEN = 13; /**< File/Dir already opened */ + ERROR_STORAGE_DIR_NOT_EMPTY = 18; /**< Directory, you're going to remove is not empty */ + + /**< Application Errors */ + ERROR_APP_CANT_START = 16; /**< Can't start app - internal error */ + ERROR_APP_SYSTEM_LOCKED = 17; /**< Another app is running */ + ERROR_APP_NOT_RUNNING = 21; /**< App is not running or doesn't support RPC commands */ + ERROR_APP_CMD_ERROR = 22; /**< Command execution error */ + + /**< Virtual Display Errors */ + ERROR_VIRTUAL_DISPLAY_ALREADY_STARTED = 19; /**< Virtual Display session can't be started twice */ + ERROR_VIRTUAL_DISPLAY_NOT_STARTED = 20; /**< Virtual Display session can't be stopped when it's not started */ + + /**< GPIO Errors */ + ERROR_GPIO_MODE_INCORRECT = 58; + ERROR_GPIO_UNKNOWN_PIN_MODE = 59; +} + +/* There are Server commands (e.g. Storage_write), which have no body message + * in response. But 'oneof' obligate to have at least 1 encoded message + * in scope. For this needs Empty message is implemented. + */ +message Empty { +} + +message StopSession { +} + +message Main { + uint32 command_id = 1; + CommandStatus command_status = 2; + bool has_next = 3; + oneof content { + Empty empty = 4; + StopSession stop_session = 19; + .PB_System.PingRequest system_ping_request = 5; + .PB_System.PingResponse system_ping_response = 6; + .PB_System.RebootRequest system_reboot_request = 31; + .PB_System.DeviceInfoRequest system_device_info_request = 32; + .PB_System.DeviceInfoResponse system_device_info_response = 33; + .PB_System.FactoryResetRequest system_factory_reset_request = 34; + .PB_System.GetDateTimeRequest system_get_datetime_request = 35; + .PB_System.GetDateTimeResponse system_get_datetime_response = 36; + .PB_System.SetDateTimeRequest system_set_datetime_request = 37; + .PB_System.PlayAudiovisualAlertRequest system_play_audiovisual_alert_request = 38; + .PB_System.ProtobufVersionRequest system_protobuf_version_request = 39; + .PB_System.ProtobufVersionResponse system_protobuf_version_response = 40; + .PB_System.UpdateRequest system_update_request = 41; + .PB_System.UpdateResponse system_update_response = 46; + .PB_System.PowerInfoRequest system_power_info_request = 44; + .PB_System.PowerInfoResponse system_power_info_response = 45; + .PB_Storage.InfoRequest storage_info_request = 28; + .PB_Storage.InfoResponse storage_info_response = 29; + .PB_Storage.TimestampRequest storage_timestamp_request = 59; + .PB_Storage.TimestampResponse storage_timestamp_response = 60; + .PB_Storage.StatRequest storage_stat_request = 24; + .PB_Storage.StatResponse storage_stat_response = 25; + .PB_Storage.ListRequest storage_list_request = 7; + .PB_Storage.ListResponse storage_list_response = 8; + .PB_Storage.ReadRequest storage_read_request = 9; + .PB_Storage.ReadResponse storage_read_response = 10; + .PB_Storage.WriteRequest storage_write_request = 11; + .PB_Storage.DeleteRequest storage_delete_request = 12; + .PB_Storage.MkdirRequest storage_mkdir_request = 13; + .PB_Storage.Md5sumRequest storage_md5sum_request = 14; + .PB_Storage.Md5sumResponse storage_md5sum_response = 15; + .PB_Storage.RenameRequest storage_rename_request = 30; + .PB_Storage.BackupCreateRequest storage_backup_create_request = 42; + .PB_Storage.BackupRestoreRequest storage_backup_restore_request = 43; + .PB_Storage.TarExtractRequest storage_tar_extract_request = 71; + .PB_App.StartRequest app_start_request = 16; + .PB_App.LockStatusRequest app_lock_status_request = 17; + .PB_App.LockStatusResponse app_lock_status_response = 18; + .PB_App.AppExitRequest app_exit_request = 47; + .PB_App.AppLoadFileRequest app_load_file_request = 48; + .PB_App.AppButtonPressRequest app_button_press_request = 49; + .PB_App.AppButtonReleaseRequest app_button_release_request = 50; + .PB_App.AppButtonPressReleaseRequest app_button_press_release_request = 75; + .PB_App.GetErrorRequest app_get_error_request = 63; + .PB_App.GetErrorResponse app_get_error_response = 64; + .PB_App.DataExchangeRequest app_data_exchange_request = 65; + .PB_Gui.StartScreenStreamRequest gui_start_screen_stream_request = 20; + .PB_Gui.StopScreenStreamRequest gui_stop_screen_stream_request = 21; + .PB_Gui.ScreenFrame gui_screen_frame = 22; + .PB_Gui.SendInputEventRequest gui_send_input_event_request = 23; + .PB_Gui.StartVirtualDisplayRequest gui_start_virtual_display_request = 26; + .PB_Gui.StopVirtualDisplayRequest gui_stop_virtual_display_request = 27; + .PB_Gpio.SetPinMode gpio_set_pin_mode = 51; + .PB_Gpio.SetInputPull gpio_set_input_pull = 52; + .PB_Gpio.GetPinMode gpio_get_pin_mode = 53; + .PB_Gpio.GetPinModeResponse gpio_get_pin_mode_response = 54; + .PB_Gpio.ReadPin gpio_read_pin = 55; + .PB_Gpio.ReadPinResponse gpio_read_pin_response = 56; + .PB_Gpio.WritePin gpio_write_pin = 57; + .PB_Gpio.GetOtgMode gpio_get_otg_mode = 72; + .PB_Gpio.GetOtgModeResponse gpio_get_otg_mode_response = 73; + .PB_Gpio.SetOtgMode gpio_set_otg_mode = 74; + .PB_App.AppStateResponse app_state_response = 58; + .PB_Property.GetRequest property_get_request = 61; + .PB_Property.GetResponse property_get_response = 62; + .PB_Desktop.IsLockedRequest desktop_is_locked_request = 66; + .PB_Desktop.UnlockRequest desktop_unlock_request = 67; + .PB_Desktop.StatusSubscribeRequest desktop_status_subscribe_request = 68; + .PB_Desktop.StatusUnsubscribeRequest desktop_status_unsubscribe_request = 69; + .PB_Desktop.Status desktop_status = 70; + } +} + +message Region { + message Band { + uint32 start = 1; + uint32 end = 2; + int32 power_limit = 3; + uint32 duty_cycle = 4; + } + + bytes country_code = 1; + repeated Band bands = 2; +} diff --git a/components/bridge/pbutils/src/main/proto/gpio.options b/components/bridge/pbutils/src/main/proto/gpio.options new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/bridge/pbutils/src/main/proto/gpio.proto b/components/bridge/pbutils/src/main/proto/gpio.proto new file mode 100644 index 0000000000..236767be02 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/gpio.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; + +package PB_Gpio; +option java_package = "com.flipperdevices.protobuf.gpio"; + +enum GpioPin { + PC0 = 0; + PC1 = 1; + PC3 = 2; + PB2 = 3; + PB3 = 4; + PA4 = 5; + PA6 = 6; + PA7 = 7; +}; + +enum GpioPinMode { + OUTPUT = 0; + INPUT = 1; +}; + +enum GpioInputPull { + NO = 0; + UP = 1; + DOWN = 2; +}; + +enum GpioOtgMode { + OFF = 0; + ON = 1; +}; + +message SetPinMode { + GpioPin pin = 1; + GpioPinMode mode = 2; +} + +message SetInputPull { + GpioPin pin = 1; + GpioInputPull pull_mode = 2; +} + +message GetPinMode { + GpioPin pin = 1; +} + +message GetPinModeResponse { + GpioPinMode mode = 1; +} + +message ReadPin { + GpioPin pin = 1; +} + +message ReadPinResponse { + uint32 value = 2; +} + +message WritePin { + GpioPin pin = 1; + uint32 value = 2; +} + +message GetOtgMode { +}; + +message GetOtgModeResponse { + GpioOtgMode mode = 1; +}; + +message SetOtgMode { + GpioOtgMode mode = 1; +}; diff --git a/components/bridge/pbutils/src/main/proto/gui.options b/components/bridge/pbutils/src/main/proto/gui.options new file mode 100644 index 0000000000..a5efc3e3f9 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/gui.options @@ -0,0 +1,2 @@ +PB_Gui.ScreenFrame.data type:FT_POINTER +PB_Gui.ScreenFrame.data max_size:1024 \ No newline at end of file diff --git a/components/bridge/pbutils/src/main/proto/gui.proto b/components/bridge/pbutils/src/main/proto/gui.proto new file mode 100644 index 0000000000..dbd5144fc8 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/gui.proto @@ -0,0 +1,52 @@ +syntax = "proto3"; + +package PB_Gui; +option java_package = "com.flipperdevices.protobuf.screen"; + +enum InputKey { + UP = 0; + DOWN = 1; + RIGHT = 2; + LEFT = 3; + OK = 4; + BACK = 5; +}; + +enum InputType { + PRESS = 0; /**< Press event, emitted after de-bounce */ + RELEASE = 1; /**< Release event, emitted after de-bounce */ + SHORT = 2; /**< Short event, emitted after InputTypeRelease done withing INPUT_LONG_PRESS interval */ + LONG = 3; /**< Long event, emitted after INPUT_LONG_PRESS interval, asynchronous to InputTypeRelease */ + REPEAT = 4; /**< Repeat event, emitted with INPUT_REPEATE_PRESS period after InputTypeLong event */ +} + +enum ScreenOrientation { + HORIZONTAL = 0; /**< Horizontal */ + HORIZONTAL_FLIP = 1; /**< Horizontal flipped (180) */ + VERTICAL = 2; /**< Vertical (90) */ + VERTICAL_FLIP = 3; /**< Vertical flipped (270) */ +} + +message ScreenFrame { + bytes data = 1; + ScreenOrientation orientation = 2; +} + +message StartScreenStreamRequest { +} + +message StopScreenStreamRequest { +} + +message SendInputEventRequest { + InputKey key = 1; + InputType type = 2; +} + +message StartVirtualDisplayRequest { + ScreenFrame first_frame = 1; /**< Optional: screen frame to show */ + bool send_input = 2; /**< Optional: send flipper input */ +} + +message StopVirtualDisplayRequest { +} \ No newline at end of file diff --git a/components/bridge/pbutils/src/main/proto/property.options b/components/bridge/pbutils/src/main/proto/property.options new file mode 100644 index 0000000000..3cfad35b51 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/property.options @@ -0,0 +1,3 @@ +PB_Property.GetRequest.key type:FT_POINTER +PB_Property.GetResponse.key type:FT_POINTER +PB_Property.GetResponse.value type:FT_POINTER diff --git a/components/bridge/pbutils/src/main/proto/property.proto b/components/bridge/pbutils/src/main/proto/property.proto new file mode 100644 index 0000000000..2f164ce048 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/property.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package PB_Property; +option java_package = "com.flipperdevices.protobuf.property"; + +message GetRequest { + string key = 1; +} + +message GetResponse { + string key = 1; + string value = 2; +} diff --git a/components/bridge/pbutils/src/main/proto/storage.options b/components/bridge/pbutils/src/main/proto/storage.options new file mode 100644 index 0000000000..8e99754fdd --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/storage.options @@ -0,0 +1,26 @@ +PB_Storage.File.name type:FT_POINTER +PB_Storage.File.data type:FT_POINTER +PB_Storage.InfoRequest.path type:FT_POINTER +PB_Storage.TimestampRequest.path type:FT_POINTER +PB_Storage.StatRequest.path type:FT_POINTER +PB_Storage.ListRequest.path type:FT_POINTER +PB_Storage.ReadRequest.path type:FT_POINTER +PB_Storage.WriteRequest.path type:FT_POINTER +PB_Storage.DeleteRequest.path type:FT_POINTER +PB_Storage.MkdirRequest.path type:FT_POINTER +PB_Storage.Md5sumRequest.path type:FT_POINTER +PB_Storage.RenameRequest.old_path type:FT_POINTER +PB_Storage.RenameRequest.new_path type:FT_POINTER +PB_Storage.BackupCreateRequest.archive_path type:FT_POINTER +PB_Storage.BackupRestoreRequest.archive_path type:FT_POINTER +PB_Storage.TarExtractRequest.tar_path type:FT_POINTER +PB_Storage.TarExtractRequest.out_path type:FT_POINTER + +PB_Storage.ListResponse.file max_count:8 + +// not affected by nanopb, so server & client should keep in mind these max values +PB_Storage.File.data max_size:512 +PB_Storage.Md5sumResponse.md5sum max_length:32 +PB_Storage.File.md5sum max_length:32 +PB_Storage.*.path max_length:255 + diff --git a/components/bridge/pbutils/src/main/proto/storage.proto b/components/bridge/pbutils/src/main/proto/storage.proto new file mode 100644 index 0000000000..eb6269bfb0 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/storage.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; + +package PB_Storage; +option java_package = "com.flipperdevices.protobuf.storage"; + +message File { + enum FileType { + FILE = 0; // default value + DIR = 1; + } + FileType type = 1; + string name = 2; + uint32 size = 3; + bytes data = 4; + string md5sum = 5; +} + +message InfoRequest { + string path = 1; +} + +message InfoResponse { + uint64 total_space = 1; + uint64 free_space = 2; +} + +message TimestampRequest { + string path = 1; +} + +message TimestampResponse { + uint32 timestamp = 1; +} + +message StatRequest { + string path = 1; +} + +message StatResponse { + File file = 1; +} + +message ListRequest { + string path = 1; + bool include_md5 = 2; + uint32 filter_max_size = 3; +} + +message ListResponse { + repeated File file = 1; +} + +message ReadRequest { + string path = 1; +} + +message ReadResponse { + File file = 1; +} + +message WriteRequest { + string path = 1; + File file = 2; +} + +message DeleteRequest { + string path = 1; + bool recursive = 2; +} + +message MkdirRequest { + string path = 1; +} + +message Md5sumRequest { + string path = 1; +} + +message Md5sumResponse { + string md5sum = 1; +} + +message RenameRequest { + string old_path = 1; + string new_path = 2; +} + +message BackupCreateRequest { + string archive_path = 1; +} + +message BackupRestoreRequest { + string archive_path = 1; +} + +message TarExtractRequest { + string tar_path = 1; + string out_path = 2; +} diff --git a/components/bridge/pbutils/src/main/proto/system.options b/components/bridge/pbutils/src/main/proto/system.options new file mode 100644 index 0000000000..b400c3eeb2 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/system.options @@ -0,0 +1,16 @@ +PB_System.PingRequest.data type:FT_POINTER +PB_System.PingRequest.data max_size:1024 +PB_System.PingResponse.data type:FT_POINTER +PB_System.PingResponse.data max_size:1024 +PB_System.DeviceInfoResponse.key type:FT_POINTER +PB_System.DeviceInfoResponse.value type:FT_POINTER +PB_System.DateTime.hour int_size:IS_8 +PB_System.DateTime.minute int_size:IS_8 +PB_System.DateTime.second int_size:IS_8 +PB_System.DateTime.day int_size:IS_8 +PB_System.DateTime.month int_size:IS_8 +PB_System.DateTime.year int_size:IS_16 +PB_System.DateTime.weekday int_size:IS_8 +PB_System.UpdateRequest.update_manifest type:FT_POINTER +PB_System.PowerInfoResponse.key type:FT_POINTER +PB_System.PowerInfoResponse.value type:FT_POINTER diff --git a/components/bridge/pbutils/src/main/proto/system.proto b/components/bridge/pbutils/src/main/proto/system.proto new file mode 100644 index 0000000000..90238e8f34 --- /dev/null +++ b/components/bridge/pbutils/src/main/proto/system.proto @@ -0,0 +1,95 @@ +syntax = "proto3"; + +package PB_System; +option java_package = "com.flipperdevices.protobuf.system"; + +message PingRequest { + bytes data = 1; +} + +message PingResponse { + bytes data = 1; +} + +message RebootRequest { + enum RebootMode { + OS = 0; // default value + DFU = 1; + UPDATE = 2; + } + RebootMode mode = 1; +} + +message DeviceInfoRequest { +} + +message DeviceInfoResponse { + string key = 1; + string value = 2; +} + +message FactoryResetRequest { +} + +message GetDateTimeRequest { +} + +message GetDateTimeResponse { + DateTime datetime = 1; +} + +message SetDateTimeRequest { + DateTime datetime = 1; +} + +message DateTime { + // Time + uint32 hour = 1; /**< Hour in 24H format: 0-23 */ + uint32 minute = 2; /**< Minute: 0-59 */ + uint32 second = 3; /**< Second: 0-59 */ + // Date + uint32 day = 4; /**< Current day: 1-31 */ + uint32 month = 5; /**< Current month: 1-12 */ + uint32 year = 6; /**< Current year: 2000-2099 */ + uint32 weekday = 7; /**< Current weekday: 1-7 */ +} + +message PlayAudiovisualAlertRequest { +} + +message ProtobufVersionRequest { +} + +message ProtobufVersionResponse { + uint32 major = 1; + uint32 minor = 2; +} + +message UpdateRequest { + string update_manifest = 1; +} + +message UpdateResponse { + enum UpdateResultCode { + OK = 0; + ManifestPathInvalid = 1; + ManifestFolderNotFound = 2; + ManifestInvalid = 3; + StageMissing = 4; + StageIntegrityError = 5; + ManifestPointerError = 6; + TargetMismatch = 7; + OutdatedManifestVersion = 8; + IntFull = 9; + UnspecifiedError = 10; + } + UpdateResultCode code = 1; +} + +message PowerInfoRequest { +} + +message PowerInfoResponse { + string key = 1; + string value = 2; +} From 47b35fc816b18cc5e1cbaf131e8d71a54e746712 Mon Sep 17 00:00:00 2001 From: Nikita Kulikov Date: Fri, 24 Jan 2025 21:30:47 +0000 Subject: [PATCH 4/6] Fix lint --- CHANGELOG.md | 1 + .../search/BLESearchConnectionDelegate.kt | 1 - .../screens/search/USBSearchDelegate.kt | 3 +- .../ConnectionSearchDecomposeComponent.kt | 48 ++------------ .../search/ConnectionSearchDelegate.kt | 2 +- .../screens/search/ConnectionSearchItem.kt | 2 +- .../search/ConnectionSearchItemComposable.kt | 66 +++++++++++++++++++ .../search/ConnectionSearchViewModel.kt | 2 - .../screens/search/USBSearchDelegate.kt | 1 - .../usb/impl/model/USBAndroidDevice.kt | 2 - .../usb/impl/model/USBAndroidDeviceFactory.kt | 3 +- .../usb/impl/model/USBSerialListener.kt | 2 +- .../usb/impl/model/USBDesktopDevice.kt | 1 - .../usb/impl/model/USBDesktopDeviceFactory.kt | 2 +- .../usb/impl/di/BleDeviceConnectionModule.kt | 1 - .../usb/impl/model/USBPlatformDevice.kt | 4 +- .../impl/model/USBPlatformDeviceFactory.kt | 2 +- 17 files changed, 79 insertions(+), 64 deletions(-) create mode 100644 components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItemComposable.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 82d0fded8c..4fdc3c0a77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ # 1.8.2 - In Progress +- [Feature] Add USB connection option to sample # 1.8.1 diff --git a/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchConnectionDelegate.kt b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchConnectionDelegate.kt index 20adc0caaa..d6002324c5 100644 --- a/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchConnectionDelegate.kt +++ b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/BLESearchConnectionDelegate.kt @@ -21,7 +21,6 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach -import me.gulya.anvil.assisted.ContributesAssistedFactory import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.kotlin.ble.core.scanner.BleScanMode import no.nordicsemi.android.kotlin.ble.core.scanner.BleScannerSettings diff --git a/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt index 436168a9c6..ebabe1dc94 100644 --- a/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt +++ b/components/bridge/connection/sample/shared/src/androidMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt @@ -58,7 +58,7 @@ class USBSearchDelegate @AssistedInject constructor( .filterIsInstance() .associateBy { it.portPath } - info { searchDevices.joinToString(",") { "${it}" } } + info { searchDevices.joinToString(",") { "$it" } } searchItems.emit( searchDevices.map { it.toFDeviceFlipperZeroUSBModel() }.map { usbDevice -> @@ -78,7 +78,6 @@ class USBSearchDelegate @AssistedInject constructor( override fun getDevicesFlow() = searchItems.asStateFlow() - @AssistedFactory @ContributesMultibinding(AppGraph::class, ConnectionSearchDelegate.Factory::class) fun interface Factory : ConnectionSearchDelegate.Factory { diff --git a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDecomposeComponent.kt b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDecomposeComponent.kt index 330a146067..16da3c754e 100644 --- a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDecomposeComponent.kt +++ b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDecomposeComponent.kt @@ -25,16 +25,11 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import flipperapp.components.bridge.connection.sample.shared.generated.resources.Res import flipperapp.components.bridge.connection.sample.shared.generated.resources.connection_search_title -import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_add_box -import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_delete import flipperapp.components.core.ui.res.generated.resources.material_ic_close import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import javax.inject.Provider import flipperapp.components.core.ui.res.generated.resources.Res as SharedRes -import com.flipperdevices.bridge.connection.config.api.FDeviceType -import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_bluetooth -import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_usb class ConnectionSearchDecomposeComponent @AssistedInject constructor( @Assisted componentContext: ComponentContext, @@ -71,45 +66,10 @@ class ConnectionSearchDecomposeComponent @AssistedInject constructor( devices, key = { device -> device.address } ) { searchItem -> - Row { - Icon( - modifier = Modifier - .padding(16.dp) - .size(24.dp), - painter = painterResource( - when(searchItem.deviceModel.type) { - FDeviceType.FLIPPER_ZERO_BLE -> Res.drawable.material_ic_bluetooth - FDeviceType.FLIPPER_ZERO_USB -> Res.drawable.material_ic_usb - } - ), - contentDescription = null, - tint = LocalPallet.current.text100 - ) - - Text( - modifier = Modifier - .weight(1f) - .padding(16.dp), - text = searchItem.deviceModel.humanReadableName, - color = LocalPallet.current.text100 - ) - - Icon( - modifier = Modifier - .clickableRipple { searchViewModel.onDeviceClick(searchItem) } - .padding(16.dp) - .size(24.dp), - painter = painterResource( - if (searchItem.isAdded) { - Res.drawable.material_ic_delete - } else { - Res.drawable.material_ic_add_box - } - ), - contentDescription = null, - tint = LocalPallet.current.text100 - ) - } + ConnectionSearchItemComposable( + searchItem, + onDeviceClick = { searchViewModel.onDeviceClick(searchItem) } + ) } } } diff --git a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDelegate.kt b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDelegate.kt index d547eebcbc..81af8bd32f 100644 --- a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDelegate.kt +++ b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchDelegate.kt @@ -11,4 +11,4 @@ interface ConnectionSearchDelegate { scope: CoroutineScope, ): ConnectionSearchDelegate } -} \ No newline at end of file +} diff --git a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItem.kt b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItem.kt index b8bacce30c..73ca96e4e2 100644 --- a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItem.kt +++ b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItem.kt @@ -6,4 +6,4 @@ data class ConnectionSearchItem( val address: String, val deviceModel: FDeviceBaseModel, val isAdded: Boolean -) \ No newline at end of file +) diff --git a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItemComposable.kt b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItemComposable.kt new file mode 100644 index 0000000000..17c5057526 --- /dev/null +++ b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchItemComposable.kt @@ -0,0 +1,66 @@ +package com.flipperdevices.bridge.connection.screens.search + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.flipperdevices.bridge.connection.config.api.FDeviceType +import com.flipperdevices.core.ui.ktx.clickableRipple +import com.flipperdevices.core.ui.theme.LocalPallet +import flipperapp.components.bridge.connection.sample.shared.generated.resources.Res +import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_add_box +import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_bluetooth +import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_delete +import flipperapp.components.bridge.connection.sample.shared.generated.resources.material_ic_usb +import org.jetbrains.compose.resources.painterResource + +@Composable +fun ConnectionSearchItemComposable( + searchItem: ConnectionSearchItem, + onDeviceClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Row(modifier) { + Icon( + modifier = Modifier + .padding(16.dp) + .size(24.dp), + painter = painterResource( + when (searchItem.deviceModel.type) { + FDeviceType.FLIPPER_ZERO_BLE -> Res.drawable.material_ic_bluetooth + FDeviceType.FLIPPER_ZERO_USB -> Res.drawable.material_ic_usb + } + ), + contentDescription = null, + tint = LocalPallet.current.text100 + ) + + Text( + modifier = Modifier + .weight(1f) + .padding(16.dp), + text = searchItem.deviceModel.humanReadableName, + color = LocalPallet.current.text100 + ) + + Icon( + modifier = Modifier + .clickableRipple(onClick = onDeviceClick) + .padding(16.dp) + .size(24.dp), + painter = painterResource( + if (searchItem.isAdded) { + Res.drawable.material_ic_delete + } else { + Res.drawable.material_ic_add_box + } + ), + contentDescription = null, + tint = LocalPallet.current.text100 + ) + } +} diff --git a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchViewModel.kt b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchViewModel.kt index c50c203757..08424dce04 100644 --- a/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchViewModel.kt +++ b/components/bridge/connection/sample/shared/src/commonMain/kotlin/com/flipperdevices/bridge/connection/screens/search/ConnectionSearchViewModel.kt @@ -2,11 +2,9 @@ package com.flipperdevices.bridge.connection.screens.search import com.flipperdevices.bridge.connection.config.api.FDevicePersistedStorage import com.flipperdevices.core.ui.lifecycle.DecomposeViewModel -import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch diff --git a/components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt b/components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt index 9354ac3ba4..185828e656 100644 --- a/components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt +++ b/components/bridge/connection/sample/shared/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/screens/search/USBSearchDelegate.kt @@ -72,7 +72,6 @@ class USBSearchDelegate @AssistedInject constructor( override fun getDevicesFlow() = searchItems.asStateFlow() - @AssistedFactory @ContributesMultibinding(AppGraph::class, ConnectionSearchDelegate.Factory::class) fun interface Factory : ConnectionSearchDelegate.Factory { diff --git a/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDevice.kt b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDevice.kt index bbb1ab27a1..887fe0bb90 100644 --- a/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDevice.kt +++ b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDevice.kt @@ -3,7 +3,6 @@ package com.flipperdevices.bridge.connection.transport.usb.impl.model import android.app.PendingIntent import android.content.Intent import android.hardware.usb.UsbManager -import android.util.Log import com.flipperdevices.core.activityholder.CurrentActivityHolder import com.flipperdevices.core.log.LogTagProvider import com.flipperdevices.core.log.error @@ -57,7 +56,6 @@ class USBAndroidDevice( private fun requestPermission() { if (!usbManager.hasPermission(serialDriver.device)) { - val intent = Intent("Test") val activity = CurrentActivityHolder.getCurrentActivity() diff --git a/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDeviceFactory.kt b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDeviceFactory.kt index ed20fb3183..e21a0324ce 100644 --- a/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDeviceFactory.kt +++ b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBAndroidDeviceFactory.kt @@ -9,7 +9,6 @@ import com.squareup.anvil.annotations.ContributesBinding import kotlinx.coroutines.CoroutineScope import javax.inject.Inject - @ContributesBinding(AppGraph::class, USBPlatformDeviceFactory::class) class USBAndroidDeviceFactory @Inject constructor( private val context: Context @@ -33,4 +32,4 @@ class USBAndroidDeviceFactory @Inject constructor( scope = scope ) } -} \ No newline at end of file +} diff --git a/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBSerialListener.kt b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBSerialListener.kt index e629b88733..db8b93ee3f 100644 --- a/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBSerialListener.kt +++ b/components/bridge/connection/transport/usb/impl/src/androidMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBSerialListener.kt @@ -71,4 +71,4 @@ private fun Any.wait() { @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") private fun Any.notifyAll() { (this as Object).notifyAll() -} \ No newline at end of file +} diff --git a/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDevice.kt b/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDevice.kt index f1c8d351fc..6b97f9ea1f 100644 --- a/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDevice.kt +++ b/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDevice.kt @@ -1,7 +1,6 @@ package com.flipperdevices.bridge.connection.transport.usb.impl.model import com.fazecast.jSerialComm.SerialPort -import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig private const val OPEN_PORT_TIME_MS = 1000 diff --git a/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDeviceFactory.kt b/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDeviceFactory.kt index 662eba66cf..8526a35e54 100644 --- a/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDeviceFactory.kt +++ b/components/bridge/connection/transport/usb/impl/src/desktopMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBDesktopDeviceFactory.kt @@ -15,4 +15,4 @@ class USBDesktopDeviceFactory @Inject constructor() : USBPlatformDeviceFactory { ): USBPlatformDevice { return USBDesktopDevice(SerialPort.getCommPort(config.path)) } -} \ No newline at end of file +} diff --git a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/di/BleDeviceConnectionModule.kt b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/di/BleDeviceConnectionModule.kt index 4cbf56cc13..5c6ddd87e5 100644 --- a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/di/BleDeviceConnectionModule.kt +++ b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/di/BleDeviceConnectionModule.kt @@ -5,7 +5,6 @@ import com.flipperdevices.bridge.connection.transport.common.api.di.DeviceConnec import com.flipperdevices.bridge.connection.transport.common.api.di.toHolder import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig import com.flipperdevices.bridge.connection.transport.usb.impl.USBDeviceConnectionApiImpl -import com.flipperdevices.bridge.connection.transport.usb.impl.model.USBPlatformDevice import com.flipperdevices.bridge.connection.transport.usb.impl.model.USBPlatformDeviceFactory import com.flipperdevices.core.di.AppGraph import com.squareup.anvil.annotations.ContributesTo diff --git a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDevice.kt b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDevice.kt index e9b8db8cee..8b2d67fe35 100644 --- a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDevice.kt +++ b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDevice.kt @@ -1,7 +1,5 @@ package com.flipperdevices.bridge.connection.transport.usb.impl.model -import com.flipperdevices.bridge.connection.transport.usb.api.FUSBDeviceConnectionConfig - interface USBPlatformDevice { fun connect(baudRate: Int, dataBits: Int, stopBits: Int, parity: Int): Boolean fun closePort() @@ -23,4 +21,4 @@ interface USBPlatformDevice { const val ONE_POINT_FIVE_STOP_BITS: Int = 2 const val TWO_STOP_BITS: Int = 3 } -} \ No newline at end of file +} diff --git a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDeviceFactory.kt b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDeviceFactory.kt index 75037b37aa..e06e7090eb 100644 --- a/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDeviceFactory.kt +++ b/components/bridge/connection/transport/usb/impl/src/jvmSharedMain/kotlin/com/flipperdevices/bridge/connection/transport/usb/impl/model/USBPlatformDeviceFactory.kt @@ -8,4 +8,4 @@ interface USBPlatformDeviceFactory { config: FUSBDeviceConnectionConfig, scope: CoroutineScope ): USBPlatformDevice -} \ No newline at end of file +} From ad9866da6b8999c8f7f71f22c2ae004ddeae70ef Mon Sep 17 00:00:00 2001 From: Nikita Kulikov Date: Fri, 24 Jan 2025 21:38:11 +0000 Subject: [PATCH 5/6] Revert submodule bad changes --- .../pbutils/src/main/proto/.github/CODEOWNERS | 3 - .../main/proto/.github/workflows/generate.yml | 30 ---- .../bridge/pbutils/src/main/proto/.gitignore | 8 - .../bridge/pbutils/src/main/proto/Changelog | 105 ------------ .../src/main/proto/application.options | 8 - .../pbutils/src/main/proto/application.proto | 58 ------- .../pbutils/src/main/proto/desktop.proto | 20 --- .../pbutils/src/main/proto/flipper.options | 6 - .../pbutils/src/main/proto/flipper.proto | 151 ------------------ .../pbutils/src/main/proto/gpio.options | 0 .../bridge/pbutils/src/main/proto/gpio.proto | 73 --------- .../bridge/pbutils/src/main/proto/gui.options | 2 - .../bridge/pbutils/src/main/proto/gui.proto | 52 ------ .../pbutils/src/main/proto/property.options | 3 - .../pbutils/src/main/proto/property.proto | 13 -- .../pbutils/src/main/proto/storage.options | 26 --- .../pbutils/src/main/proto/storage.proto | 99 ------------ .../pbutils/src/main/proto/system.options | 16 -- .../pbutils/src/main/proto/system.proto | 95 ----------- 19 files changed, 768 deletions(-) delete mode 100644 components/bridge/pbutils/src/main/proto/.github/CODEOWNERS delete mode 100644 components/bridge/pbutils/src/main/proto/.github/workflows/generate.yml delete mode 100644 components/bridge/pbutils/src/main/proto/.gitignore delete mode 100644 components/bridge/pbutils/src/main/proto/Changelog delete mode 100644 components/bridge/pbutils/src/main/proto/application.options delete mode 100644 components/bridge/pbutils/src/main/proto/application.proto delete mode 100644 components/bridge/pbutils/src/main/proto/desktop.proto delete mode 100644 components/bridge/pbutils/src/main/proto/flipper.options delete mode 100644 components/bridge/pbutils/src/main/proto/flipper.proto delete mode 100644 components/bridge/pbutils/src/main/proto/gpio.options delete mode 100644 components/bridge/pbutils/src/main/proto/gpio.proto delete mode 100644 components/bridge/pbutils/src/main/proto/gui.options delete mode 100644 components/bridge/pbutils/src/main/proto/gui.proto delete mode 100644 components/bridge/pbutils/src/main/proto/property.options delete mode 100644 components/bridge/pbutils/src/main/proto/property.proto delete mode 100644 components/bridge/pbutils/src/main/proto/storage.options delete mode 100644 components/bridge/pbutils/src/main/proto/storage.proto delete mode 100644 components/bridge/pbutils/src/main/proto/system.options delete mode 100644 components/bridge/pbutils/src/main/proto/system.proto diff --git a/components/bridge/pbutils/src/main/proto/.github/CODEOWNERS b/components/bridge/pbutils/src/main/proto/.github/CODEOWNERS deleted file mode 100644 index dfe56a07f4..0000000000 --- a/components/bridge/pbutils/src/main/proto/.github/CODEOWNERS +++ /dev/null @@ -1,3 +0,0 @@ -# Who owns all the code by default - -* @DrZlo13 @skotopes @gornekich @nminaylov @hedger diff --git a/components/bridge/pbutils/src/main/proto/.github/workflows/generate.yml b/components/bridge/pbutils/src/main/proto/.github/workflows/generate.yml deleted file mode 100644 index 16d34a769c..0000000000 --- a/components/bridge/pbutils/src/main/proto/.github/workflows/generate.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: 'Generate protobuf sources' - -on: - push: - -jobs: - generate: - runs-on: ubuntu-latest - steps: - - name: Checkout flipperzero-protobuf - uses: actions/checkout@v2 - - - name: Checkout nanopb - uses: actions/checkout@v2 - with: - repository: nanopb/nanopb - path: nanopb - - - name: Setup python - uses: actions/setup-python@v3 - with: - python-version: '3.9' - - - name: Setup protobuf - run: | - sudo apt -y install protobuf-compiler - python3 -m pip install --upgrade python3-protobuf==2.5.0 protobuf==3.20.1 grpcio-tools==1.47.0 grpcio==1.47.0 - - - name: Generate sources - run: python3 nanopb/generator/nanopb_generator.py -q -I . -D /tmp *.proto diff --git a/components/bridge/pbutils/src/main/proto/.gitignore b/components/bridge/pbutils/src/main/proto/.gitignore deleted file mode 100644 index 34165a8706..0000000000 --- a/components/bridge/pbutils/src/main/proto/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# JetBrains IDEs -.idea - -# MacOS -.DS_Store - -# Visual Studio Code -.vscode/ \ No newline at end of file diff --git a/components/bridge/pbutils/src/main/proto/Changelog b/components/bridge/pbutils/src/main/proto/Changelog deleted file mode 100644 index be5fa9c29f..0000000000 --- a/components/bridge/pbutils/src/main/proto/Changelog +++ /dev/null @@ -1,105 +0,0 @@ -# Changelog - -## [0.21] -### Added -- Application AppButtonPressRequest now supports button indices in addition to names. - -## [0.20] -### Added -- Storage ListRequest message now has a file size filter. - -## [0.19] -### Added -- Storage ListRequest message now supports md5sum calculation for each file - -## [0.18] -### Added -- Loader is now able to load apps from SD card - -## [0.17] -### Added -- Desktop service subscription API - -## [0.16] -### Added -- Desktop service API - -## [0.15] -### Modified -- ScreenFrame: additional orientation field - -## [0.14] -### Added -- New subsystem: Property -- Property messages: GetRequest, GetResponse -- App messages: GetErrorRequest, GetErrorResponse, DataExchangeRequest - -## [0.13] -### Added -- Storage: timestamp - -## [0.12] -### Added -- Region message - -## [0.11] -### Added -- App messages: AppStateResponse - -## [0.10] -### Added -- GPIO message: SetPinMode, SetInputPull, GetPinMode, GetPinModeResponse, ReadPin, ReadPinResponse, WritePin - -## [0.9] -### Added -- System message: UpdateResponse, enum UpdateResultCode: new entries - OutdatedManifestVersion, IntFull, UnspecifiedError - -## [0.8] -### Added -- App messages: AppExitRequest, AppLoadFileRequest, AppButtonPressRequest, AppButtonReleaseRequest - -## [0.7] -### Added -- System message: UpdateResponse: passing update preparation detailed status - -## [0.6] -### Added -- System message: RebootRequest: added UPDATE restart mode -### Fixed -- System message: UpdateRequest: renamed manifest field - -## [0.5] -### Added -- System message: PowerInfo - -## [0.4] -### Added -- System message: UpdateRequest -- Storage messages: BackupCreateRequest, BackupRestoreRequest - -## [0.3] -### Fixed -- BLE disconnection after writing / erasing FLASH - -## [0.2] -### Added -- System messages: ProtobufVersion -- Support parallel RPC sessions -- Screen streaming optimization - -## [0.1] -### Added -- Code owners -- CI setup -- System messages: Ping, Reboot, DeviceInfo, FactoryReset, DateTime, - AudiovisualAlert -- Storage messages: Info, Stat, Read, Write, Delete, Mkdir, Md5sum, - Rename -- App messages: Start, LockStatus -- Gui messages: ScreenStream, ScreenFrame, SendInput, VirtualDisplay - -## [0.0] -### Added -- Introduced Flipper Zero Protobuf repository -- StorageList messages diff --git a/components/bridge/pbutils/src/main/proto/application.options b/components/bridge/pbutils/src/main/proto/application.options deleted file mode 100644 index 338bb67d61..0000000000 --- a/components/bridge/pbutils/src/main/proto/application.options +++ /dev/null @@ -1,8 +0,0 @@ -PB_App.StartRequest.args type:FT_POINTER -PB_App.StartRequest.args max_length:512 -PB_App.StartRequest.name type:FT_POINTER -PB_App.StartRequest.name max_length:512 -PB_App.AppLoadFileRequest.path max_length:512 -PB_App.AppButtonPressRequest.args max_length:512 -PB_App.GetErrorResponse.text type:FT_POINTER -PB_App.DataExchangeRequest.data type:FT_POINTER diff --git a/components/bridge/pbutils/src/main/proto/application.proto b/components/bridge/pbutils/src/main/proto/application.proto deleted file mode 100644 index 4c82cdf91f..0000000000 --- a/components/bridge/pbutils/src/main/proto/application.proto +++ /dev/null @@ -1,58 +0,0 @@ -syntax = "proto3"; - -package PB_App; -option java_package = "com.flipperdevices.protobuf.app"; - -message StartRequest { - string name = 1; - string args = 2; -} - -message LockStatusRequest { -} - -message LockStatusResponse { - bool locked = 1; -} - -message AppExitRequest { -} - -message AppLoadFileRequest { - string path = 1; -} - -message AppButtonPressRequest { - string args = 1; - int32 index = 2; -} - -message AppButtonReleaseRequest { -} - -message AppButtonPressReleaseRequest { - string args = 1; - int32 index = 2; -} - -enum AppState { - APP_CLOSED = 0; - APP_STARTED = 1; -}; - -message AppStateResponse { - AppState state = 1; -} - -message GetErrorRequest { -} - -message GetErrorResponse { - uint32 code = 1; - string text = 2; -} - -message DataExchangeRequest { - bytes data = 1; -} - diff --git a/components/bridge/pbutils/src/main/proto/desktop.proto b/components/bridge/pbutils/src/main/proto/desktop.proto deleted file mode 100644 index cc8212d40c..0000000000 --- a/components/bridge/pbutils/src/main/proto/desktop.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto3"; - -package PB_Desktop; -option java_package = "com.flipperdevices.protobuf.desktop"; - -message IsLockedRequest { -} - -message UnlockRequest { -} - -message StatusSubscribeRequest { -} - -message StatusUnsubscribeRequest { -} - -message Status { - bool locked = 1; -} diff --git a/components/bridge/pbutils/src/main/proto/flipper.options b/components/bridge/pbutils/src/main/proto/flipper.options deleted file mode 100644 index 0301133444..0000000000 --- a/components/bridge/pbutils/src/main/proto/flipper.options +++ /dev/null @@ -1,6 +0,0 @@ -PB.Main submsg_callback:true -PB.Region.country_code type:FT_POINTER -PB.Region.country_code max_size:2 -PB.Region.Band.power_limit int_size:IS_8 -PB.Region.Band.duty_cycle int_size:IS_8 - diff --git a/components/bridge/pbutils/src/main/proto/flipper.proto b/components/bridge/pbutils/src/main/proto/flipper.proto deleted file mode 100644 index 2ba75dadce..0000000000 --- a/components/bridge/pbutils/src/main/proto/flipper.proto +++ /dev/null @@ -1,151 +0,0 @@ -syntax = "proto3"; -import "storage.proto"; -import "system.proto"; -import "application.proto"; -import "gui.proto"; -import "gpio.proto"; -import "property.proto"; -import "desktop.proto"; - -package PB; -option java_package = "com.flipperdevices.protobuf"; - -enum CommandStatus { - OK = 0; - - /**< Common Errors */ - ERROR = 1; /**< Unknown error */ - ERROR_DECODE = 2; /**< Command can't be decoded successfully - command_id in response may be wrong! */ - ERROR_NOT_IMPLEMENTED = 3; /**< Command successfully decoded, but not implemented (deprecated or not yet implemented) */ - ERROR_BUSY = 4; /**< Somebody took global lock, so not all commands are available */ - ERROR_CONTINUOUS_COMMAND_INTERRUPTED = 14; /**< Not received has_next == 0 */ - ERROR_INVALID_PARAMETERS = 15; /**< not provided (or provided invalid) crucial parameters to perform RPC */ - - /**< Storage Errors */ - ERROR_STORAGE_NOT_READY = 5; /**< FS not ready */ - ERROR_STORAGE_EXIST = 6; /**< File/Dir already exist */ - ERROR_STORAGE_NOT_EXIST = 7; /**< File/Dir does not exist */ - ERROR_STORAGE_INVALID_PARAMETER = 8; /**< Invalid API parameter */ - ERROR_STORAGE_DENIED = 9; /**< Access denied */ - ERROR_STORAGE_INVALID_NAME = 10; /**< Invalid name/path */ - ERROR_STORAGE_INTERNAL = 11; /**< Internal error */ - ERROR_STORAGE_NOT_IMPLEMENTED = 12; /**< Function is not implemented */ - ERROR_STORAGE_ALREADY_OPEN = 13; /**< File/Dir already opened */ - ERROR_STORAGE_DIR_NOT_EMPTY = 18; /**< Directory, you're going to remove is not empty */ - - /**< Application Errors */ - ERROR_APP_CANT_START = 16; /**< Can't start app - internal error */ - ERROR_APP_SYSTEM_LOCKED = 17; /**< Another app is running */ - ERROR_APP_NOT_RUNNING = 21; /**< App is not running or doesn't support RPC commands */ - ERROR_APP_CMD_ERROR = 22; /**< Command execution error */ - - /**< Virtual Display Errors */ - ERROR_VIRTUAL_DISPLAY_ALREADY_STARTED = 19; /**< Virtual Display session can't be started twice */ - ERROR_VIRTUAL_DISPLAY_NOT_STARTED = 20; /**< Virtual Display session can't be stopped when it's not started */ - - /**< GPIO Errors */ - ERROR_GPIO_MODE_INCORRECT = 58; - ERROR_GPIO_UNKNOWN_PIN_MODE = 59; -} - -/* There are Server commands (e.g. Storage_write), which have no body message - * in response. But 'oneof' obligate to have at least 1 encoded message - * in scope. For this needs Empty message is implemented. - */ -message Empty { -} - -message StopSession { -} - -message Main { - uint32 command_id = 1; - CommandStatus command_status = 2; - bool has_next = 3; - oneof content { - Empty empty = 4; - StopSession stop_session = 19; - .PB_System.PingRequest system_ping_request = 5; - .PB_System.PingResponse system_ping_response = 6; - .PB_System.RebootRequest system_reboot_request = 31; - .PB_System.DeviceInfoRequest system_device_info_request = 32; - .PB_System.DeviceInfoResponse system_device_info_response = 33; - .PB_System.FactoryResetRequest system_factory_reset_request = 34; - .PB_System.GetDateTimeRequest system_get_datetime_request = 35; - .PB_System.GetDateTimeResponse system_get_datetime_response = 36; - .PB_System.SetDateTimeRequest system_set_datetime_request = 37; - .PB_System.PlayAudiovisualAlertRequest system_play_audiovisual_alert_request = 38; - .PB_System.ProtobufVersionRequest system_protobuf_version_request = 39; - .PB_System.ProtobufVersionResponse system_protobuf_version_response = 40; - .PB_System.UpdateRequest system_update_request = 41; - .PB_System.UpdateResponse system_update_response = 46; - .PB_System.PowerInfoRequest system_power_info_request = 44; - .PB_System.PowerInfoResponse system_power_info_response = 45; - .PB_Storage.InfoRequest storage_info_request = 28; - .PB_Storage.InfoResponse storage_info_response = 29; - .PB_Storage.TimestampRequest storage_timestamp_request = 59; - .PB_Storage.TimestampResponse storage_timestamp_response = 60; - .PB_Storage.StatRequest storage_stat_request = 24; - .PB_Storage.StatResponse storage_stat_response = 25; - .PB_Storage.ListRequest storage_list_request = 7; - .PB_Storage.ListResponse storage_list_response = 8; - .PB_Storage.ReadRequest storage_read_request = 9; - .PB_Storage.ReadResponse storage_read_response = 10; - .PB_Storage.WriteRequest storage_write_request = 11; - .PB_Storage.DeleteRequest storage_delete_request = 12; - .PB_Storage.MkdirRequest storage_mkdir_request = 13; - .PB_Storage.Md5sumRequest storage_md5sum_request = 14; - .PB_Storage.Md5sumResponse storage_md5sum_response = 15; - .PB_Storage.RenameRequest storage_rename_request = 30; - .PB_Storage.BackupCreateRequest storage_backup_create_request = 42; - .PB_Storage.BackupRestoreRequest storage_backup_restore_request = 43; - .PB_Storage.TarExtractRequest storage_tar_extract_request = 71; - .PB_App.StartRequest app_start_request = 16; - .PB_App.LockStatusRequest app_lock_status_request = 17; - .PB_App.LockStatusResponse app_lock_status_response = 18; - .PB_App.AppExitRequest app_exit_request = 47; - .PB_App.AppLoadFileRequest app_load_file_request = 48; - .PB_App.AppButtonPressRequest app_button_press_request = 49; - .PB_App.AppButtonReleaseRequest app_button_release_request = 50; - .PB_App.AppButtonPressReleaseRequest app_button_press_release_request = 75; - .PB_App.GetErrorRequest app_get_error_request = 63; - .PB_App.GetErrorResponse app_get_error_response = 64; - .PB_App.DataExchangeRequest app_data_exchange_request = 65; - .PB_Gui.StartScreenStreamRequest gui_start_screen_stream_request = 20; - .PB_Gui.StopScreenStreamRequest gui_stop_screen_stream_request = 21; - .PB_Gui.ScreenFrame gui_screen_frame = 22; - .PB_Gui.SendInputEventRequest gui_send_input_event_request = 23; - .PB_Gui.StartVirtualDisplayRequest gui_start_virtual_display_request = 26; - .PB_Gui.StopVirtualDisplayRequest gui_stop_virtual_display_request = 27; - .PB_Gpio.SetPinMode gpio_set_pin_mode = 51; - .PB_Gpio.SetInputPull gpio_set_input_pull = 52; - .PB_Gpio.GetPinMode gpio_get_pin_mode = 53; - .PB_Gpio.GetPinModeResponse gpio_get_pin_mode_response = 54; - .PB_Gpio.ReadPin gpio_read_pin = 55; - .PB_Gpio.ReadPinResponse gpio_read_pin_response = 56; - .PB_Gpio.WritePin gpio_write_pin = 57; - .PB_Gpio.GetOtgMode gpio_get_otg_mode = 72; - .PB_Gpio.GetOtgModeResponse gpio_get_otg_mode_response = 73; - .PB_Gpio.SetOtgMode gpio_set_otg_mode = 74; - .PB_App.AppStateResponse app_state_response = 58; - .PB_Property.GetRequest property_get_request = 61; - .PB_Property.GetResponse property_get_response = 62; - .PB_Desktop.IsLockedRequest desktop_is_locked_request = 66; - .PB_Desktop.UnlockRequest desktop_unlock_request = 67; - .PB_Desktop.StatusSubscribeRequest desktop_status_subscribe_request = 68; - .PB_Desktop.StatusUnsubscribeRequest desktop_status_unsubscribe_request = 69; - .PB_Desktop.Status desktop_status = 70; - } -} - -message Region { - message Band { - uint32 start = 1; - uint32 end = 2; - int32 power_limit = 3; - uint32 duty_cycle = 4; - } - - bytes country_code = 1; - repeated Band bands = 2; -} diff --git a/components/bridge/pbutils/src/main/proto/gpio.options b/components/bridge/pbutils/src/main/proto/gpio.options deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/bridge/pbutils/src/main/proto/gpio.proto b/components/bridge/pbutils/src/main/proto/gpio.proto deleted file mode 100644 index 236767be02..0000000000 --- a/components/bridge/pbutils/src/main/proto/gpio.proto +++ /dev/null @@ -1,73 +0,0 @@ -syntax = "proto3"; - -package PB_Gpio; -option java_package = "com.flipperdevices.protobuf.gpio"; - -enum GpioPin { - PC0 = 0; - PC1 = 1; - PC3 = 2; - PB2 = 3; - PB3 = 4; - PA4 = 5; - PA6 = 6; - PA7 = 7; -}; - -enum GpioPinMode { - OUTPUT = 0; - INPUT = 1; -}; - -enum GpioInputPull { - NO = 0; - UP = 1; - DOWN = 2; -}; - -enum GpioOtgMode { - OFF = 0; - ON = 1; -}; - -message SetPinMode { - GpioPin pin = 1; - GpioPinMode mode = 2; -} - -message SetInputPull { - GpioPin pin = 1; - GpioInputPull pull_mode = 2; -} - -message GetPinMode { - GpioPin pin = 1; -} - -message GetPinModeResponse { - GpioPinMode mode = 1; -} - -message ReadPin { - GpioPin pin = 1; -} - -message ReadPinResponse { - uint32 value = 2; -} - -message WritePin { - GpioPin pin = 1; - uint32 value = 2; -} - -message GetOtgMode { -}; - -message GetOtgModeResponse { - GpioOtgMode mode = 1; -}; - -message SetOtgMode { - GpioOtgMode mode = 1; -}; diff --git a/components/bridge/pbutils/src/main/proto/gui.options b/components/bridge/pbutils/src/main/proto/gui.options deleted file mode 100644 index a5efc3e3f9..0000000000 --- a/components/bridge/pbutils/src/main/proto/gui.options +++ /dev/null @@ -1,2 +0,0 @@ -PB_Gui.ScreenFrame.data type:FT_POINTER -PB_Gui.ScreenFrame.data max_size:1024 \ No newline at end of file diff --git a/components/bridge/pbutils/src/main/proto/gui.proto b/components/bridge/pbutils/src/main/proto/gui.proto deleted file mode 100644 index dbd5144fc8..0000000000 --- a/components/bridge/pbutils/src/main/proto/gui.proto +++ /dev/null @@ -1,52 +0,0 @@ -syntax = "proto3"; - -package PB_Gui; -option java_package = "com.flipperdevices.protobuf.screen"; - -enum InputKey { - UP = 0; - DOWN = 1; - RIGHT = 2; - LEFT = 3; - OK = 4; - BACK = 5; -}; - -enum InputType { - PRESS = 0; /**< Press event, emitted after de-bounce */ - RELEASE = 1; /**< Release event, emitted after de-bounce */ - SHORT = 2; /**< Short event, emitted after InputTypeRelease done withing INPUT_LONG_PRESS interval */ - LONG = 3; /**< Long event, emitted after INPUT_LONG_PRESS interval, asynchronous to InputTypeRelease */ - REPEAT = 4; /**< Repeat event, emitted with INPUT_REPEATE_PRESS period after InputTypeLong event */ -} - -enum ScreenOrientation { - HORIZONTAL = 0; /**< Horizontal */ - HORIZONTAL_FLIP = 1; /**< Horizontal flipped (180) */ - VERTICAL = 2; /**< Vertical (90) */ - VERTICAL_FLIP = 3; /**< Vertical flipped (270) */ -} - -message ScreenFrame { - bytes data = 1; - ScreenOrientation orientation = 2; -} - -message StartScreenStreamRequest { -} - -message StopScreenStreamRequest { -} - -message SendInputEventRequest { - InputKey key = 1; - InputType type = 2; -} - -message StartVirtualDisplayRequest { - ScreenFrame first_frame = 1; /**< Optional: screen frame to show */ - bool send_input = 2; /**< Optional: send flipper input */ -} - -message StopVirtualDisplayRequest { -} \ No newline at end of file diff --git a/components/bridge/pbutils/src/main/proto/property.options b/components/bridge/pbutils/src/main/proto/property.options deleted file mode 100644 index 3cfad35b51..0000000000 --- a/components/bridge/pbutils/src/main/proto/property.options +++ /dev/null @@ -1,3 +0,0 @@ -PB_Property.GetRequest.key type:FT_POINTER -PB_Property.GetResponse.key type:FT_POINTER -PB_Property.GetResponse.value type:FT_POINTER diff --git a/components/bridge/pbutils/src/main/proto/property.proto b/components/bridge/pbutils/src/main/proto/property.proto deleted file mode 100644 index 2f164ce048..0000000000 --- a/components/bridge/pbutils/src/main/proto/property.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -package PB_Property; -option java_package = "com.flipperdevices.protobuf.property"; - -message GetRequest { - string key = 1; -} - -message GetResponse { - string key = 1; - string value = 2; -} diff --git a/components/bridge/pbutils/src/main/proto/storage.options b/components/bridge/pbutils/src/main/proto/storage.options deleted file mode 100644 index 8e99754fdd..0000000000 --- a/components/bridge/pbutils/src/main/proto/storage.options +++ /dev/null @@ -1,26 +0,0 @@ -PB_Storage.File.name type:FT_POINTER -PB_Storage.File.data type:FT_POINTER -PB_Storage.InfoRequest.path type:FT_POINTER -PB_Storage.TimestampRequest.path type:FT_POINTER -PB_Storage.StatRequest.path type:FT_POINTER -PB_Storage.ListRequest.path type:FT_POINTER -PB_Storage.ReadRequest.path type:FT_POINTER -PB_Storage.WriteRequest.path type:FT_POINTER -PB_Storage.DeleteRequest.path type:FT_POINTER -PB_Storage.MkdirRequest.path type:FT_POINTER -PB_Storage.Md5sumRequest.path type:FT_POINTER -PB_Storage.RenameRequest.old_path type:FT_POINTER -PB_Storage.RenameRequest.new_path type:FT_POINTER -PB_Storage.BackupCreateRequest.archive_path type:FT_POINTER -PB_Storage.BackupRestoreRequest.archive_path type:FT_POINTER -PB_Storage.TarExtractRequest.tar_path type:FT_POINTER -PB_Storage.TarExtractRequest.out_path type:FT_POINTER - -PB_Storage.ListResponse.file max_count:8 - -// not affected by nanopb, so server & client should keep in mind these max values -PB_Storage.File.data max_size:512 -PB_Storage.Md5sumResponse.md5sum max_length:32 -PB_Storage.File.md5sum max_length:32 -PB_Storage.*.path max_length:255 - diff --git a/components/bridge/pbutils/src/main/proto/storage.proto b/components/bridge/pbutils/src/main/proto/storage.proto deleted file mode 100644 index eb6269bfb0..0000000000 --- a/components/bridge/pbutils/src/main/proto/storage.proto +++ /dev/null @@ -1,99 +0,0 @@ -syntax = "proto3"; - -package PB_Storage; -option java_package = "com.flipperdevices.protobuf.storage"; - -message File { - enum FileType { - FILE = 0; // default value - DIR = 1; - } - FileType type = 1; - string name = 2; - uint32 size = 3; - bytes data = 4; - string md5sum = 5; -} - -message InfoRequest { - string path = 1; -} - -message InfoResponse { - uint64 total_space = 1; - uint64 free_space = 2; -} - -message TimestampRequest { - string path = 1; -} - -message TimestampResponse { - uint32 timestamp = 1; -} - -message StatRequest { - string path = 1; -} - -message StatResponse { - File file = 1; -} - -message ListRequest { - string path = 1; - bool include_md5 = 2; - uint32 filter_max_size = 3; -} - -message ListResponse { - repeated File file = 1; -} - -message ReadRequest { - string path = 1; -} - -message ReadResponse { - File file = 1; -} - -message WriteRequest { - string path = 1; - File file = 2; -} - -message DeleteRequest { - string path = 1; - bool recursive = 2; -} - -message MkdirRequest { - string path = 1; -} - -message Md5sumRequest { - string path = 1; -} - -message Md5sumResponse { - string md5sum = 1; -} - -message RenameRequest { - string old_path = 1; - string new_path = 2; -} - -message BackupCreateRequest { - string archive_path = 1; -} - -message BackupRestoreRequest { - string archive_path = 1; -} - -message TarExtractRequest { - string tar_path = 1; - string out_path = 2; -} diff --git a/components/bridge/pbutils/src/main/proto/system.options b/components/bridge/pbutils/src/main/proto/system.options deleted file mode 100644 index b400c3eeb2..0000000000 --- a/components/bridge/pbutils/src/main/proto/system.options +++ /dev/null @@ -1,16 +0,0 @@ -PB_System.PingRequest.data type:FT_POINTER -PB_System.PingRequest.data max_size:1024 -PB_System.PingResponse.data type:FT_POINTER -PB_System.PingResponse.data max_size:1024 -PB_System.DeviceInfoResponse.key type:FT_POINTER -PB_System.DeviceInfoResponse.value type:FT_POINTER -PB_System.DateTime.hour int_size:IS_8 -PB_System.DateTime.minute int_size:IS_8 -PB_System.DateTime.second int_size:IS_8 -PB_System.DateTime.day int_size:IS_8 -PB_System.DateTime.month int_size:IS_8 -PB_System.DateTime.year int_size:IS_16 -PB_System.DateTime.weekday int_size:IS_8 -PB_System.UpdateRequest.update_manifest type:FT_POINTER -PB_System.PowerInfoResponse.key type:FT_POINTER -PB_System.PowerInfoResponse.value type:FT_POINTER diff --git a/components/bridge/pbutils/src/main/proto/system.proto b/components/bridge/pbutils/src/main/proto/system.proto deleted file mode 100644 index 90238e8f34..0000000000 --- a/components/bridge/pbutils/src/main/proto/system.proto +++ /dev/null @@ -1,95 +0,0 @@ -syntax = "proto3"; - -package PB_System; -option java_package = "com.flipperdevices.protobuf.system"; - -message PingRequest { - bytes data = 1; -} - -message PingResponse { - bytes data = 1; -} - -message RebootRequest { - enum RebootMode { - OS = 0; // default value - DFU = 1; - UPDATE = 2; - } - RebootMode mode = 1; -} - -message DeviceInfoRequest { -} - -message DeviceInfoResponse { - string key = 1; - string value = 2; -} - -message FactoryResetRequest { -} - -message GetDateTimeRequest { -} - -message GetDateTimeResponse { - DateTime datetime = 1; -} - -message SetDateTimeRequest { - DateTime datetime = 1; -} - -message DateTime { - // Time - uint32 hour = 1; /**< Hour in 24H format: 0-23 */ - uint32 minute = 2; /**< Minute: 0-59 */ - uint32 second = 3; /**< Second: 0-59 */ - // Date - uint32 day = 4; /**< Current day: 1-31 */ - uint32 month = 5; /**< Current month: 1-12 */ - uint32 year = 6; /**< Current year: 2000-2099 */ - uint32 weekday = 7; /**< Current weekday: 1-7 */ -} - -message PlayAudiovisualAlertRequest { -} - -message ProtobufVersionRequest { -} - -message ProtobufVersionResponse { - uint32 major = 1; - uint32 minor = 2; -} - -message UpdateRequest { - string update_manifest = 1; -} - -message UpdateResponse { - enum UpdateResultCode { - OK = 0; - ManifestPathInvalid = 1; - ManifestFolderNotFound = 2; - ManifestInvalid = 3; - StageMissing = 4; - StageIntegrityError = 5; - ManifestPointerError = 6; - TargetMismatch = 7; - OutdatedManifestVersion = 8; - IntFull = 9; - UnspecifiedError = 10; - } - UpdateResultCode code = 1; -} - -message PowerInfoRequest { -} - -message PowerInfoResponse { - string key = 1; - string value = 2; -} From 4ec575af77ade51b0b40c6a257879532708b0ce7 Mon Sep 17 00:00:00 2001 From: Nikita Kulikov Date: Fri, 24 Jan 2025 21:54:12 +0000 Subject: [PATCH 6/6] Add submodule back --- components/bridge/pbutils/src/main/proto | 1 + 1 file changed, 1 insertion(+) create mode 160000 components/bridge/pbutils/src/main/proto diff --git a/components/bridge/pbutils/src/main/proto b/components/bridge/pbutils/src/main/proto new file mode 160000 index 0000000000..ee5b6a22fd --- /dev/null +++ b/components/bridge/pbutils/src/main/proto @@ -0,0 +1 @@ +Subproject commit ee5b6a22fd6aaf9075a2b7bd373309592e6627c5