Sync changes

This commit is contained in:
Sylwester Zieliński
2023-07-28 13:39:52 +02:00
parent 2870ef109e
commit 4f769e90c2
53 changed files with 548 additions and 337 deletions

View File

@@ -65,9 +65,9 @@ dependencies {
implementation(libs.nordic.core)
implementation(libs.nordic.theme)
implementation(libs.nordic.navigation)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.uilogger)
implementation(libs.nordic.permission)
implementation(libs.nordic.permissions.ble)
implementation(libs.nordic.analytics)
implementation(libs.nordic.ble.common)

View File

@@ -33,7 +33,8 @@
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.kotlin.kapt) apply true
alias(libs.plugins.kotlin.kapt) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.kotlin.parcelize) apply false
alias(libs.plugins.hilt) apply false

View File

@@ -37,7 +37,7 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects

238
gradle/libs.versions.toml Normal file
View File

@@ -0,0 +1,238 @@
[versions]
accompanist = "0.30.1"
androidDesugarJdkLibs = "2.0.3"
androidGradlePlugin = "8.1.0"
androidxActivity = "1.7.2"
androidxAnnotation = "1.6.0"
androidxAppCompat = "1.6.1"
androidxComposeBom = "2023.06.01" # https://developer.android.com/jetpack/compose/bom/bom-mapping
androidxComposeCompiler = "1.5.1" # https://developer.android.com/jetpack/androidx/releases/compose-kotlin
androidxComposeRuntimeTracing = "1.0.0-alpha03"
androidxCore = "1.10.1"
androidxCoreSplashscreen = "1.0.1"
androidxDataStore = "1.0.0"
androidxEspresso = "3.5.1"
androidxHiltNavigationCompose = "1.0.0"
androidxLifecycle = "2.6.1"
androidxLocalbroadcastmanager = "1.1.0"
androidxMacroBenchmark = "1.1.1"
androidxNavigation = "2.6.0"
androidxMetrics = "1.0.0-alpha04"
androidxProfileinstaller = "1.3.1"
androidxStartup = "1.1.1"
androidxWindowManager = "1.1.0"
androidxTestCore = "1.5.0"
androidxTestExt = "1.1.5"
androidxTestRunner = "1.5.2"
androidxTestRules = "1.5.0"
androidxTracing = "1.1.0"
androidxUiAutomator = "2.2.0"
androidxWork = "2.8.1"
coil = "2.4.0"
firebaseBom = "32.2.0"
hilt = "2.47"
hiltExt = "1.0.0"
jacoco = "0.8.7"
junit4 = "4.13.2"
kotlin = "1.9.0"
kotlinxCoroutines = "1.7.3"
kotlinxDatetime = "0.4.0"
kotlinxSerializationJson = "1.5.1"
ksp = "1.9.0-1.0.12"
lint = "31.1.0"
memfault-cloud = "2.0.5"
okhttp = "4.11.0"
protobuf = "3.23.4"
protobufPlugin = "0.9.4"
publishPlugin = "1.2.0"
retrofit = "2.9.0"
retrofitKotlinxSerializationJson = "1.0.0"
room = "2.5.2"
secrets = "2.0.1"
turbine = "1.0.0"
markdown = "0.3.0"
wirePlugin = "4.7.2"
timber = "5.0.1"
chart = "v3.1.0"
leakcanary = "2.12"
mockk = "1.13.5"
slf4j = "2.0.7"
robolectric = "4.10.3"
skydovesBallon = "1.5.4"
moshiKotlin = "1.15.0"
moshiAdapters = "1.15.0"
okio = "3.4.0"
nordic-blek = "0.2.1"
nordic-ble = "2.6.1"
nordic-dfu = "2.3.0"
nordic-log = "2.3.0"
nordic-mcumgr = "1.7.0"
nordic-scanner = "1.6.0"
nordic-common = "1.8.0"
nordic-memfault = "1.0.2"
nordicPlugins = "1.7.1"
dokkaPlugin = "1.8.20"
googleServicesPlugins = "4.3.15"
firebaseCrashlyticsPlugins = "2.9.2"
[libraries]
accompanist-flowlayout = { group = "com.google.accompanist", name = "accompanist-flowlayout", version.ref = "accompanist" }
accompanist-swiperefresh = { group = "com.google.accompanist", name = "accompanist-swiperefresh", version.ref = "accompanist" }
accompanist-systemuicontroller = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "accompanist" }
accompanist-pager = { group = "com.google.accompanist", name = "accompanist-pager", version.ref = "accompanist" }
accompanist-pagerindicators = { group = "com.google.accompanist", name = "accompanist-pager-indicators", version.ref = "accompanist" }
accompanist-placeholder = { group = "com.google.accompanist", name = "accompanist-placeholder-material", version.ref = "accompanist" }
android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" }
androidx-annotation = { group = "androidx.annotation", name = "annotation", version.ref = "androidxAnnotation" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidxAppCompat" }
androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidxMacroBenchmark" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" }
androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" }
androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" }
androidx-compose-material = { group = "androidx.compose.material", name = "material" }
androidx-compose-material-iconsExtended = { group = "androidx.compose.material", name = "material-icons-extended" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-compose-material3-windowSizeClass = {group = "androidx.compose.material3", name = "material3-window-size-class" }
androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" }
androidx-compose-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata" }
androidx-compose-runtime-tracing = { group = "androidx.compose.runtime", name = "runtime-tracing", version.ref = "androidxComposeRuntimeTracing" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-compose-ui-test = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-compose-ui-testManifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" }
androidx-core = { group = "androidx.core", name = "core", version.ref = "androidxCore" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidxCore" }
androidx-core-splashscreen = { group = "androidx.core", name = "core-splashscreen", version.ref = "androidxCoreSplashscreen" }
androidx-dataStore-core = { group = "androidx.datastore", name = "datastore", version.ref = "androidxDataStore" }
androidx-dataStore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "androidxDataStore" }
androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidxHiltNavigationCompose" }
androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "androidxLifecycle" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidxLifecycle" }
androidx-lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime", version.ref = "androidxLifecycle" }
androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-service = { group = "androidx.lifecycle", name = "lifecycle-service", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewModel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewModel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewModel-savedState = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-savedstate", version.ref = "androidxLifecycle" }
androidx-localbroadcastmanager = { group = "androidx.localbroadcastmanager", name = "localbroadcastmanager", version.ref = "androidxLocalbroadcastmanager" }
androidx-metrics = { group = "androidx.metrics", name = "metrics-performance", version.ref = "androidxMetrics" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidxNavigation" }
androidx-navigation-testing = { group = "androidx.navigation", name = "navigation-testing", version.ref = "androidxNavigation" }
androidx-profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "androidxProfileinstaller" }
androidx-startup = { group = "androidx.startup", name = "startup-runtime", version.ref = "androidxStartup" }
androidx-window-manager = {module = "androidx.window:window", version.ref = "androidxWindowManager"}
androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidxTestCore" }
androidx-test-ext = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "androidxTestExt" }
androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidxEspresso" }
androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidxTestRunner" }
androidx-test-rules = { group = "androidx.test", name = "rules", version.ref = "androidxTestRules" }
androidx-test-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "androidxUiAutomator" }
androidx-tracing-ktx = {group = "androidx.tracing", name="tracing-ktx", version.ref = "androidxTracing" }
androidx-work-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "androidxWork" }
androidx-work-testing = { group = "androidx.work", name = "work-testing", version.ref = "androidxWork" }
coil-kt = { group = "io.coil-kt", name = "coil", version.ref = "coil"}
coil-kt-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil"}
coil-kt-svg = { group = "io.coil-kt", name = "coil-svg", version.ref = "coil"}
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom"}
firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics-ktx" }
firebase-database = { group = "com.google.firebase", name = "firebase-database-ktx" }
firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics-ktx" }
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-ext-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "hiltExt" }
hilt-ext-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "hiltExt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
hilt-android-testing = { group = "com.google.dagger", name = "hilt-android-testing", version.ref = "hilt" }
junit4 = { group = "junit", name = "junit", version.ref = "junit4" }
kotlin-junit = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit", version.ref = "kotlin" }
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" }
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" }
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" }
kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" }
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
lint-api = { group = "com.android.tools.lint", name = "lint-api", version.ref = "lint" }
okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
protobuf-protoc = { group = "com.google.protobuf", name = "protoc", version.ref = "protobuf" }
protobuf-kotlin-lite = { group = "com.google.protobuf", name = "protobuf-kotlin-lite", version.ref = "protobuf" }
turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" }
retrofit-core = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
retrofit-kotlin-serialization = { group = "com.jakewharton.retrofit", name = "retrofit2-kotlinx-serialization-converter", version.ref = "retrofitKotlinxSerializationJson" }
room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
markdown = { group = "com.github.jeziellago", name = "compose-markdown", version.ref = "markdown" }
memfault-cloud = { group = "com.memfault.cloud", name = "cloud-android", version.ref = "memfault-cloud" }
timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" }
chart = { group = "com.github.PhilJay", name = "MPAndroidChart", version.ref = "chart" }
leakcanary = { group = "com.squareup.leakcanary", name = "leakcanary-android", version.ref = "leakcanary" }
test-slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4j" }
test-mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" }
test-robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" }
skydoves-ballon = {group = "com.github.skydoves", name = "balloon-compose", version.ref = "skydovesBallon"}
moshi-kotlin = {group = "com.squareup.moshi", name = "moshi-kotlin", version.ref = "moshiKotlin"}
moshi-adapters = {group = "com.squareup.moshi", name = "moshi-adapters", version.ref = "moshiAdapters"}
okio = {group = "com.squareup.okio", name = "okio", version.ref = "okio"}
# Nordic
nordic-ble-ktx = { group = "no.nordicsemi.android", name = "ble-ktx", version.ref = "nordic-ble" }
nordic-ble-common = { group = "no.nordicsemi.android", name = "ble-common", version.ref = "nordic-ble" }
nordic-dfu = { group = "no.nordicsemi.android", name = "dfu", version.ref = "nordic-dfu" }
nordic-mcumgr-core = { group = "no.nordicsemi.android", name = "mcumgr-core", version.ref = "nordic-mcumgr" }
nordic-mcumgr-ble = { group = "no.nordicsemi.android", name = "mcumgr-ble", version.ref = "nordic-mcumgr" }
nordic-log = { group = "no.nordicsemi.android", name = "log", version.ref = "nordic-log" }
nordic-log-timber = { group = "no.nordicsemi.android", name = "log-timber", version.ref = "nordic-log" }
nordic-scanner = { group = "no.nordicsemi.android.support.v18", name = "scanner", version.ref = "nordic-scanner" }
nordic-core = { group = "no.nordicsemi.android.common", name = "core", version.ref = "nordic-common" }
nordic-theme = { group = "no.nordicsemi.android.common", name = "theme", version.ref = "nordic-common" }
nordic-analytics = { group = "no.nordicsemi.android.common", name = "analytics", version.ref = "nordic-common" }
nordic-navigation = { group = "no.nordicsemi.android.common", name = "navigation", version.ref = "nordic-common" }
nordic-uilogger = { group = "no.nordicsemi.android.common", name = "uilogger", version.ref = "nordic-common" }
nordic-logger = { group = "no.nordicsemi.android.common", name = "logger", version.ref = "nordic-common" }
nordic-permissions-nfc = { group = "no.nordicsemi.android.common", name = "permissions-nfc", version.ref = "nordic-common" }
nordic-permissions-ble = { group = "no.nordicsemi.android.common", name = "permissions-ble", version.ref = "nordic-common" }
nordic-permissions-internet = { group = "no.nordicsemi.android.common", name = "permissions-internet", version.ref = "nordic-common" }
nordic-memfault = { group = "no.nordicsemi.android", name = "memfault", version.ref = "nordic-memfault" }
# BleK
nordic-blek-client = { group = "no.nordicsemi.android.kotlin.ble", name = "client", version.ref = "nordic-blek" }
nordic-blek-server = { group = "no.nordicsemi.android.kotlin.ble", name = "server", version.ref = "nordic-blek" }
nordic-blek-profile = { group = "no.nordicsemi.android.kotlin.ble", name = "profile", version.ref = "nordic-blek" }
nordic-blek-core = { group = "no.nordicsemi.android.kotlin.ble", name = "core", version.ref = "nordic-blek" }
nordic-blek-scanner = { group = "no.nordicsemi.android.kotlin.ble", name = "scanner", version.ref = "nordic-blek" }
nordic-blek-advertiser = { group = "no.nordicsemi.android.kotlin.ble", name = "advertiser", version.ref = "nordic-blek" }
nordic-blek-uiscanner = { group = "no.nordicsemi.android.kotlin.ble", name = "uiscanner", version.ref = "nordic-blek" }
# Dependencies of the included build-logic
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
[plugins]
nordic-application = { id = "no.nordicsemi.android.gradle.application", version.ref = "nordicPlugins" }
nordic-application-compose = { id = "no.nordicsemi.android.gradle.application.compose", version.ref = "nordicPlugins" }
nordic-library = { id = "no.nordicsemi.android.gradle.library", version.ref = "nordicPlugins" }
nordic-library-compose = { id = "no.nordicsemi.android.gradle.library.compose", version.ref = "nordicPlugins" }
nordic-feature = { id = "no.nordicsemi.android.gradle.feature", version.ref = "nordicPlugins" }
nordic-hilt = { id = "no.nordicsemi.android.gradle.hilt", version.ref = "nordicPlugins" }
nordic-kotlin = { id = "no.nordicsemi.android.gradle.kotlin", version.ref = "nordicPlugins" }
nordic-nexus = { id = "no.nordicsemi.android.gradle.nexus", version.ref = "nordicPlugins" }
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
android-test = { id = "com.android.test", version.ref = "androidGradlePlugin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
kotlin-dokka = { id = "org.jetbrains.dokka", version.ref = "dokkaPlugin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
protobuf = { id = "com.google.protobuf", version.ref = "protobufPlugin" }
secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secrets" }
publish = { id = "com.gradle.plugin-publish", version.ref = "publishPlugin" }
wire = { id = "com.squareup.wire", version.ref = "wirePlugin" }
google-services = { id = "com.google.gms.google-services", version.ref = "googleServicesPlugins" }
firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlyticsPlugins" }

View File

@@ -31,7 +31,7 @@
#Mon Feb 14 14:46:55 CET 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@@ -39,7 +39,7 @@ android {
dependencies {
implementation(libs.nordic.navigation)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.blek.scanner)

View File

@@ -1,22 +0,0 @@
package no.nordicsemi.android.toolbox.scanner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("no.nordicsemi.android.toolbox.scanner.test", appContext.packageName)
}
}

View File

@@ -5,10 +5,10 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.common.navigation.createDestination
import no.nordicsemi.android.common.navigation.defineDestination
import no.nordicsemi.android.common.navigation.viewmodel.SimpleNavigationViewModel
import no.nordicsemi.android.common.ui.scanner.DeviceSelected
import no.nordicsemi.android.common.ui.scanner.ScannerScreen
import no.nordicsemi.android.common.ui.scanner.ScanningCancelled
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.ui.scanner.DeviceSelected
import no.nordicsemi.android.kotlin.ble.ui.scanner.ScannerScreen
import no.nordicsemi.android.kotlin.ble.ui.scanner.ScanningCancelled
val ScannerDestinationId = createDestination<ParcelUuid, ServerDevice>("uiscanner-destination")

View File

@@ -1,16 +0,0 @@
package no.nordicsemi.android.toolbox.scanner
import org.junit.Assert.*
import org.junit.Test
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -42,7 +42,7 @@ dependencies {
implementation(project(":lib_ui"))
implementation(libs.nordic.ble.common)
implementation(libs.nordic.ble.ktx)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.blek.core)

View File

@@ -51,4 +51,5 @@ dependencies {
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.activity.compose)
implementation(libs.nordic.blek.client)
implementation(libs.nordic.logger)
}

View File

@@ -1,10 +1,9 @@
package no.nordicsemi.android.ui.view
import android.content.Context
import no.nordicsemi.android.common.logger.BlekLogger
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
interface NordicLoggerFactory {
fun createNordicLogger(context: Context, profile: String?, key: String, name: String?): BlekLoggerAndLauncher
fun createNordicLogger(context: Context, profile: String?, key: String, name: String?): BleLoggerAndLauncher
}

View File

@@ -5,8 +5,8 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.logger.DefaultBleLogger
@Module
@InstallIn(SingletonComponent::class)
@@ -20,8 +20,8 @@ class NordicLoggerFactoryHiltModule {
profile: String?,
key: String,
name: String?,
): BlekLoggerAndLauncher {
return NordicBlekLogger.create(context, profile, key, name)
): BleLoggerAndLauncher {
return DefaultBleLogger.create(context, profile, key, name)
}
}
}

View File

@@ -40,6 +40,6 @@ android {
dependencies {
implementation(libs.nordic.navigation)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.kotlinx.coroutines.core)
}

View File

@@ -54,7 +54,7 @@ dependencies {
implementation(libs.nordic.theme)
implementation(libs.nordic.uilogger)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.androidx.compose.material.iconsExtended)
implementation(libs.androidx.hilt.navigation.compose)

View File

@@ -44,13 +44,12 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.bps.R
import no.nordicsemi.android.bps.viewmodel.BPSViewModel
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.ui.view.NavigateUpButton
import no.nordicsemi.android.ui.view.ProfileAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BPSScreen() {
val viewModel: BPSViewModel = hiltViewModel()

View File

@@ -53,13 +53,12 @@ import no.nordicsemi.android.bps.view.BPSViewEvent
import no.nordicsemi.android.bps.view.BPSViewState
import no.nordicsemi.android.bps.view.DisconnectEvent
import no.nordicsemi.android.bps.view.OpenLoggerEvent
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.logger.DefaultBleLogger
import no.nordicsemi.android.common.navigation.NavigationResult
import no.nordicsemi.android.common.navigation.Navigator
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient
import no.nordicsemi.android.kotlin.ble.client.main.connect
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -93,8 +92,8 @@ internal class BPSViewModel @Inject constructor(
private val _state = MutableStateFlow(BPSViewState())
val state = _state.asStateFlow()
private lateinit var client: BleGattClient
private lateinit var logger: BlekLoggerAndLauncher
private lateinit var client: ClientBleGatt
private lateinit var logger: BleLoggerAndLauncher
init {
navigationManager.navigateTo(ScannerDestinationId, ParcelUuid(BPS_SERVICE_UUID))
@@ -126,9 +125,9 @@ internal class BPSViewModel @Inject constructor(
private fun startGattClient(device: ServerDevice) = viewModelScope.launch {
_state.value = _state.value.copy(deviceName = device.name)
logger = NordicBlekLogger.create(context, stringConst.APP_NAME, "BPS", device.address)
logger = DefaultBleLogger.create(context, stringConst.APP_NAME, "BPS", device.address)
client = device.connect(context, logger = logger)
client = ClientBleGatt.connect(context, device, logger = logger)
client.connectionStateWithStatus
.filterNotNull()
@@ -140,14 +139,15 @@ internal class BPSViewModel @Inject constructor(
return@launch
}
client.discoverServices()
.filterNotNull()
.onEach { configureGatt(it) }
.catch { onMissingServices() }
.launchIn(viewModelScope)
try {
val services = client.discoverServices()
configureGatt(services)
} catch (e: Exception) {
onMissingServices()
}
}
private suspend fun configureGatt(services: BleGattServices) {
private suspend fun configureGatt(services: ClientBleGattServices) {
val bpsService = services.findService(BPS_SERVICE_UUID)!!
val bpmCharacteristic = bpsService.findCharacteristic(BPM_CHARACTERISTIC_UUID)!!
val icpCharacteristic = bpsService.findCharacteristic(ICP_CHARACTERISTIC_UUID)

View File

@@ -53,7 +53,7 @@ dependencies {
implementation(libs.nordic.uilogger)
implementation(libs.nordic.theme)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.navigation)
implementation(libs.nordic.core)

View File

@@ -41,8 +41,8 @@ import no.nordicsemi.android.cgms.data.CGMRecordWithSequenceNumber
import no.nordicsemi.android.cgms.data.CGMServiceCommand
import no.nordicsemi.android.cgms.data.CGMServiceData
import no.nordicsemi.android.common.core.simpleSharedFlow
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.logger.DefaultBleLogger
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -60,7 +60,7 @@ class CGMRepository @Inject constructor(
private val serviceManager: ServiceManager,
private val stringConst: StringConst
) {
private var logger: BlekLoggerAndLauncher? = null
private var logger: BleLoggerAndLauncher? = null
private val _data = MutableStateFlow(CGMServiceData())
internal val data = _data.asStateFlow()
@@ -93,7 +93,7 @@ class CGMRepository @Inject constructor(
private fun shouldClean() = !isOnScreen && !isServiceRunning
fun launch(device: ServerDevice) {
logger = NordicBlekLogger.create(context, stringConst.APP_NAME, "CGM", device.address)
logger = DefaultBleLogger.create(context, stringConst.APP_NAME, "CGM", device.address)
_data.value = _data.value.copy(deviceName = device.name)
serviceManager.startService(CGMService::class.java, device)
}

View File

@@ -41,15 +41,12 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import no.nordicsemi.android.ble.common.data.cgm.CGMSpecificOpsControlPointData
import no.nordicsemi.android.cgms.data.CGMRecordWithSequenceNumber
import no.nordicsemi.android.cgms.data.CGMServiceCommand
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient
import no.nordicsemi.android.kotlin.ble.client.main.connect
import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt
import no.nordicsemi.android.kotlin.ble.client.main.errors.GattOperationException
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -60,6 +57,8 @@ import no.nordicsemi.android.kotlin.ble.profile.cgm.CGMSpecificOpsControlPointPa
import no.nordicsemi.android.kotlin.ble.profile.cgm.CGMStatusParser
import no.nordicsemi.android.kotlin.ble.profile.cgm.data.CGMErrorCode
import no.nordicsemi.android.kotlin.ble.profile.cgm.data.CGMOpCode
import no.nordicsemi.android.kotlin.ble.profile.cgm.data.CGMSpecificOpsControlPointData
import no.nordicsemi.android.kotlin.ble.profile.gls.CGMSpecificOpsControlPointDataParser
import no.nordicsemi.android.kotlin.ble.profile.gls.RecordAccessControlPointInputParser
import no.nordicsemi.android.kotlin.ble.profile.gls.RecordAccessControlPointParser
import no.nordicsemi.android.kotlin.ble.profile.gls.data.NumberOfRecordsData
@@ -70,7 +69,6 @@ import no.nordicsemi.android.kotlin.ble.profile.racp.RACPOpCode
import no.nordicsemi.android.kotlin.ble.profile.racp.RACPResponseCode
import no.nordicsemi.android.service.DEVICE_DATA
import no.nordicsemi.android.service.NotificationService
import no.nordicsemi.android.ui.view.StringConst
import no.nordicsemi.android.utils.launchWithCatch
import java.util.*
import javax.inject.Inject
@@ -93,7 +91,7 @@ internal class CGMService : NotificationService() {
@Inject
lateinit var repository: CGMRepository
private lateinit var client: BleGattClient
private lateinit var client: ClientBleGatt
private var secured = false
@@ -101,7 +99,7 @@ internal class CGMService : NotificationService() {
private var sessionStartTime: Long = 0
private lateinit var recordAccessControlPointCharacteristic: BleGattCharacteristic
private lateinit var recordAccessControlPointCharacteristic: ClientBleGattCharacteristic
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
@@ -133,7 +131,7 @@ internal class CGMService : NotificationService() {
}
private fun startGattClient(device: ServerDevice) = lifecycleScope.launch {
client = device.connect(this@CGMService, logger = { p, s -> repository.log(p, s) })
client = ClientBleGatt.connect(this@CGMService, device, logger = { p, s -> repository.log(p, s) })
client.connectionStateWithStatus
.onEach { repository.onConnectionStateChanged(it) }
@@ -145,14 +143,15 @@ internal class CGMService : NotificationService() {
return@launch
}
client.discoverServices()
.filterNotNull()
.onEach { configureGatt(it) }
.catch { repository.onMissingServices() }
.launchIn(lifecycleScope)
try {
val services = client.discoverServices()
configureGatt(services)
} catch (e: Exception) {
repository.onMissingServices()
}
}
private suspend fun configureGatt(services: BleGattServices) {
private suspend fun configureGatt(services: ClientBleGattServices) {
val cgmService = services.findService(CGMS_SERVICE_UUID)!!
val statusCharacteristic = cgmService.findCharacteristic(CGM_STATUS_UUID)!!
val featureCharacteristic = cgmService.findCharacteristic(CGM_FEATURE_UUID)!!
@@ -225,7 +224,7 @@ internal class CGMService : NotificationService() {
}
if (sessionStartTime == 0L) {
opsControlPointCharacteristic.write(CGMSpecificOpsControlPointData.startSession(secured).value!!)
opsControlPointCharacteristic.write(CGMSpecificOpsControlPointDataParser.startSession(secured))
}
}
@@ -262,11 +261,11 @@ internal class CGMService : NotificationService() {
if (numberOfRecords > 0) {
if (repository.hasRecords) {
recordAccessControlPointCharacteristic.write(
RecordAccessControlPointInputParser.reportStoredRecordsGreaterThenOrEqualTo(repository.highestSequenceNumber).value
RecordAccessControlPointInputParser.reportStoredRecordsGreaterThenOrEqualTo(repository.highestSequenceNumber)
)
} else {
recordAccessControlPointCharacteristic.write(
RecordAccessControlPointInputParser.reportAllStoredRecords().value
RecordAccessControlPointInputParser.reportAllStoredRecords()
)
}
}
@@ -289,7 +288,7 @@ internal class CGMService : NotificationService() {
clear()
repository.onNewRequestStatus(RequestStatus.PENDING)
try {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportLastStoredRecord().value)
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportLastStoredRecord())
} catch (e: GattOperationException) {
e.printStackTrace()
repository.onNewRequestStatus(RequestStatus.FAILED)
@@ -300,7 +299,7 @@ internal class CGMService : NotificationService() {
clear()
repository.onNewRequestStatus(RequestStatus.PENDING)
try {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportFirstStoredRecord().value)
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportFirstStoredRecord())
} catch (e: GattOperationException) {
e.printStackTrace()
repository.onNewRequestStatus(RequestStatus.FAILED)
@@ -311,7 +310,7 @@ internal class CGMService : NotificationService() {
clear()
repository.onNewRequestStatus(RequestStatus.PENDING)
try {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords().value)
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords())
} catch (e: GattOperationException) {
e.printStackTrace()
repository.onNewRequestStatus(RequestStatus.FAILED)

View File

@@ -44,13 +44,12 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.cgms.R
import no.nordicsemi.android.cgms.viewmodel.CGMViewModel
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.ui.view.NavigateUpButton
import no.nordicsemi.android.ui.view.ProfileAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CGMScreen() {
val viewModel: CGMViewModel = hiltViewModel()

View File

@@ -54,7 +54,7 @@ dependencies {
implementation(libs.nordic.theme)
implementation(libs.nordic.navigation)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.core)
implementation(libs.androidx.hilt.navigation.compose)

View File

@@ -38,8 +38,8 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import no.nordicsemi.android.common.core.simpleSharedFlow
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.logger.DefaultBleLogger
import no.nordicsemi.android.csc.data.CSCServiceData
import no.nordicsemi.android.csc.data.SpeedUnit
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
@@ -61,7 +61,7 @@ class CSCRepository @Inject constructor(
private val serviceManager: ServiceManager,
private val stringConst: StringConst
) {
private var logger: BlekLoggerAndLauncher? = null
private var logger: BleLoggerAndLauncher? = null
private val _wheelSize = MutableStateFlow(WheelSizes.default)
internal val wheelSize = _wheelSize.asStateFlow()
@@ -92,7 +92,7 @@ class CSCRepository @Inject constructor(
private fun shouldClean() = !isOnScreen && !isServiceRunning
fun launch(device: ServerDevice) {
logger = NordicBlekLogger.create(context, stringConst.APP_NAME, "CSC", device.address)
logger = DefaultBleLogger.create(context, stringConst.APP_NAME, "CSC", device.address)
_data.value = _data.value.copy(deviceName = device.name)
serviceManager.startService(CSCService::class.java, device)
}

View File

@@ -41,9 +41,8 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient
import no.nordicsemi.android.kotlin.ble.client.main.connect
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -51,7 +50,6 @@ import no.nordicsemi.android.kotlin.ble.profile.battery.BatteryLevelParser
import no.nordicsemi.android.kotlin.ble.profile.csc.CSCDataParser
import no.nordicsemi.android.service.DEVICE_DATA
import no.nordicsemi.android.service.NotificationService
import no.nordicsemi.android.ui.view.NordicLoggerFactory
import java.util.*
import javax.inject.Inject
@@ -68,7 +66,7 @@ internal class CSCService : NotificationService() {
@Inject
lateinit var repository: CSCRepository
private lateinit var client: BleGattClient
private lateinit var client: ClientBleGatt
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
@@ -87,7 +85,7 @@ internal class CSCService : NotificationService() {
}
private fun startGattClient(device: ServerDevice) = lifecycleScope.launch {
client = device.connect(this@CSCService, logger = { p, s -> repository.log(p, s) })
client = ClientBleGatt.connect(this@CSCService, device, logger = { p, s -> repository.log(p, s) })
client.connectionStateWithStatus
.onEach { repository.onConnectionStateChanged(it) }
@@ -99,14 +97,15 @@ internal class CSCService : NotificationService() {
return@launch
}
client.discoverServices()
.filterNotNull()
.onEach { configureGatt(it) }
.catch { repository.onMissingServices() }
.launchIn(lifecycleScope)
try {
val services = client.discoverServices()
configureGatt(services)
} catch (e: Exception) {
repository.onMissingServices()
}
}
private suspend fun configureGatt(services: BleGattServices) {
private suspend fun configureGatt(services: ClientBleGattServices) {
val cscService = services.findService(CSC_SERVICE_UUID)!!
val cscMeasurementCharacteristic = cscService.findCharacteristic(CSC_MEASUREMENT_CHARACTERISTIC_UUID)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!

View File

@@ -42,15 +42,14 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.csc.R
import no.nordicsemi.android.csc.viewmodel.CSCViewModel
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.ui.view.NavigateUpButton
import no.nordicsemi.android.ui.view.ProfileAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CSCScreen() {
val viewModel: CSCViewModel = hiltViewModel()

View File

@@ -55,7 +55,7 @@ dependencies {
implementation(libs.nordic.ble.common)
implementation(libs.nordic.ble.ktx)
implementation(libs.nordic.theme)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.navigation)
implementation(libs.nordic.uilogger)

View File

@@ -4,11 +4,11 @@ import android.annotation.SuppressLint
import android.content.Context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import no.nordicsemi.android.common.core.DataByteArray
import no.nordicsemi.android.gls.main.viewmodel.BATTERY_LEVEL_CHARACTERISTIC_UUID
import no.nordicsemi.android.gls.main.viewmodel.BATTERY_SERVICE_UUID
import no.nordicsemi.android.gls.main.viewmodel.GLS_SERVICE_UUID
@@ -16,17 +16,17 @@ import no.nordicsemi.android.gls.main.viewmodel.GLUCOSE_MEASUREMENT_CHARACTERIST
import no.nordicsemi.android.gls.main.viewmodel.GLUCOSE_MEASUREMENT_CONTEXT_CHARACTERISTIC
import no.nordicsemi.android.gls.main.viewmodel.RACP_CHARACTERISTIC
import no.nordicsemi.android.kotlin.ble.advertiser.BleAdvertiser
import no.nordicsemi.android.kotlin.ble.core.advertiser.BleAdvertiseConfig
import no.nordicsemi.android.kotlin.ble.core.MockServerDevice
import no.nordicsemi.android.kotlin.ble.core.advertiser.BleAdvertisingConfig
import no.nordicsemi.android.kotlin.ble.core.data.BleGattPermission
import no.nordicsemi.android.kotlin.ble.core.data.BleGattProperty
import no.nordicsemi.android.kotlin.ble.profile.gls.RecordAccessControlPointInputParser
import no.nordicsemi.android.kotlin.ble.server.main.BleGattServer
import no.nordicsemi.android.kotlin.ble.server.main.service.BleGattServerServiceType
import no.nordicsemi.android.kotlin.ble.server.main.service.BleServerGattCharacteristic
import no.nordicsemi.android.kotlin.ble.server.main.service.BleServerGattCharacteristicConfig
import no.nordicsemi.android.kotlin.ble.server.main.service.BleServerGattServiceConfig
import no.nordicsemi.android.kotlin.ble.server.main.service.BluetoothGattServerConnection
import no.nordicsemi.android.kotlin.ble.server.main.ServerBleGatt
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBleGattCharacteristicConfig
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBleGattServiceConfig
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBleGattServiceType
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBluetoothGattConnection
import javax.inject.Inject
import javax.inject.Singleton
@@ -38,27 +38,27 @@ class GlsServer @Inject constructor(
private val scope: CoroutineScope
) {
lateinit var server: BleGattServer
lateinit var server: ServerBleGatt
lateinit var glsCharacteristic: BleServerGattCharacteristic
lateinit var glsContextCharacteristic: BleServerGattCharacteristic
lateinit var racpCharacteristic: BleServerGattCharacteristic
lateinit var batteryLevelCharacteristic: BleServerGattCharacteristic
lateinit var glsCharacteristic: ServerBleGattCharacteristic
lateinit var glsContextCharacteristic: ServerBleGattCharacteristic
lateinit var racpCharacteristic: ServerBleGattCharacteristic
lateinit var batteryLevelCharacteristic: ServerBleGattCharacteristic
private var lastRequest = byteArrayOf()
private var lastRequest = DataByteArray()
val YOUNGEST_RECORD = byteArrayOf(0x07, 0x00, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x05, 0x00, 0x00, 0x26, 0xD2.toByte(), 0x11)
val OLDEST_RECORD = byteArrayOf(0x07, 0x04, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x11, 0x00, 0x00, 0x82.toByte(), 0xD2.toByte(), 0x11)
val YOUNGEST_RECORD = DataByteArray.from(0x07, 0x00, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x05, 0x00, 0x00, 0x26, 0xD2.toByte(), 0x11)
val OLDEST_RECORD = DataByteArray.from(0x07, 0x04, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x11, 0x00, 0x00, 0x82.toByte(), 0xD2.toByte(), 0x11)
val records = listOf(
YOUNGEST_RECORD,
byteArrayOf(0x07, 0x01, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x08, 0x00, 0x00, 0x3D, 0xD2.toByte(), 0x11),
byteArrayOf(0x07, 0x02, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x0B, 0x00, 0x00, 0x54, 0xD2.toByte(), 0x11),
byteArrayOf(0x07, 0x03, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x0E, 0x00, 0x00, 0x6B, 0xD2.toByte(), 0x11),
DataByteArray.from(0x07, 0x01, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x08, 0x00, 0x00, 0x3D, 0xD2.toByte(), 0x11),
DataByteArray.from(0x07, 0x02, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x0B, 0x00, 0x00, 0x54, 0xD2.toByte(), 0x11),
DataByteArray.from(0x07, 0x03, 0x00, 0xDC.toByte(), 0x07, 0x01, 0x01, 0x0C, 0x1E, 0x0E, 0x00, 0x00, 0x6B, 0xD2.toByte(), 0x11),
OLDEST_RECORD
)
val racp = byteArrayOf(0x06, 0x00, 0x01, 0x01)
val racp = DataByteArray.from(0x06, 0x00, 0x01, 0x01)
fun start(
context: Context,
@@ -67,50 +67,50 @@ class GlsServer @Inject constructor(
address = "55:44:33:22:11"
),
) = scope.launch {
val gmCharacteristic = BleServerGattCharacteristicConfig(
val gmCharacteristic = ServerBleGattCharacteristicConfig(
GLUCOSE_MEASUREMENT_CHARACTERISTIC,
listOf(BleGattProperty.PROPERTY_NOTIFY),
listOf()
)
val gmContextCharacteristic = BleServerGattCharacteristicConfig(
val gmContextCharacteristic = ServerBleGattCharacteristicConfig(
GLUCOSE_MEASUREMENT_CONTEXT_CHARACTERISTIC,
listOf(BleGattProperty.PROPERTY_NOTIFY),
listOf()
)
val racpCharacteristic = BleServerGattCharacteristicConfig(
val racpCharacteristic = ServerBleGattCharacteristicConfig(
RACP_CHARACTERISTIC,
listOf(BleGattProperty.PROPERTY_INDICATE, BleGattProperty.PROPERTY_WRITE),
listOf(BleGattPermission.PERMISSION_WRITE)
)
val serviceConfig = BleServerGattServiceConfig(
val serviceConfig = ServerBleGattServiceConfig(
GLS_SERVICE_UUID,
BleGattServerServiceType.SERVICE_TYPE_PRIMARY,
ServerBleGattServiceType.SERVICE_TYPE_PRIMARY,
listOf(gmCharacteristic, gmContextCharacteristic, racpCharacteristic)
)
val batteryLevelCharacteristic = BleServerGattCharacteristicConfig(
val batteryLevelCharacteristic = ServerBleGattCharacteristicConfig(
BATTERY_LEVEL_CHARACTERISTIC_UUID,
listOf(BleGattProperty.PROPERTY_READ, BleGattProperty.PROPERTY_NOTIFY),
listOf(BleGattPermission.PERMISSION_READ)
)
val batteryService = BleServerGattServiceConfig(
val batteryService = ServerBleGattServiceConfig(
BATTERY_SERVICE_UUID,
BleGattServerServiceType.SERVICE_TYPE_PRIMARY,
ServerBleGattServiceType.SERVICE_TYPE_PRIMARY,
listOf(batteryLevelCharacteristic)
)
server = BleGattServer.create(
server = ServerBleGatt.create(
context = context,
config = arrayOf(serviceConfig, batteryService),
mock = device
)
val advertiser = BleAdvertiser.create(context)
advertiser.advertise(config = BleAdvertiseConfig(), mock = device).launchIn(scope)
advertiser.advertise(config = BleAdvertisingConfig(), mock = device).launchIn(scope)
launch {
server.connections
@@ -123,7 +123,7 @@ class GlsServer @Inject constructor(
server.stopServer()
}
private fun setUpConnection(connection: BluetoothGattServerConnection) {
private fun setUpConnection(connection: ServerBluetoothGattConnection) {
val glsService = connection.services.findService(GLS_SERVICE_UUID)!!
glsCharacteristic = glsService.findCharacteristic(GLUCOSE_MEASUREMENT_CHARACTERISTIC)!!
glsContextCharacteristic = glsService.findCharacteristic(GLUCOSE_MEASUREMENT_CONTEXT_CHARACTERISTIC)!!
@@ -137,9 +137,8 @@ class GlsServer @Inject constructor(
// startBatteryService(connection)
}
private fun startGlsService(connection: BluetoothGattServerConnection) {
private fun startGlsService(connection: ServerBluetoothGattConnection) {
racpCharacteristic.value
.filter { it.isNotEmpty() }
.onEach { lastRequest = it }
.launchIn(scope)
}
@@ -148,42 +147,42 @@ class GlsServer @Inject constructor(
sendResponse(lastRequest)
}
private fun sendResponse(request: ByteArray) {
if (request.contentEquals(RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords().value)) {
private fun sendResponse(request: DataByteArray) {
if (request == RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords()) {
sendAll(glsCharacteristic)
racpCharacteristic.setValue(racp)
} else if (request.contentEquals(RecordAccessControlPointInputParser.reportLastStoredRecord().value)) {
} else if (request == RecordAccessControlPointInputParser.reportLastStoredRecord()) {
sendLast(glsCharacteristic)
racpCharacteristic.setValue(racp)
} else if (request.contentEquals(RecordAccessControlPointInputParser.reportFirstStoredRecord().value)) {
} else if (request == RecordAccessControlPointInputParser.reportFirstStoredRecord()) {
sendFirst(glsCharacteristic)
racpCharacteristic.setValue(racp)
}
}
private fun sendFirst(characteristics: BleServerGattCharacteristic) {
private fun sendFirst(characteristics: ServerBleGattCharacteristic) {
characteristics.setValue(records.first())
}
private fun sendLast(characteristics: BleServerGattCharacteristic) {
private fun sendLast(characteristics: ServerBleGattCharacteristic) {
characteristics.setValue(records.last())
}
private fun sendAll(characteristics: BleServerGattCharacteristic) = scope.launch {
private fun sendAll(characteristics: ServerBleGattCharacteristic) = scope.launch {
records.forEach {
characteristics.setValue(it)
delay(100)
}
}
private fun startBatteryService(connection: BluetoothGattServerConnection) {
private fun startBatteryService(connection: ServerBluetoothGattConnection) {
scope.launch {
repeat(100) {
batteryLevelCharacteristic.setValue(byteArrayOf(0x61))
batteryLevelCharacteristic.setValue(DataByteArray.from(0x61))
delay(STANDARD_DELAY)
batteryLevelCharacteristic.setValue(byteArrayOf(0x60))
batteryLevelCharacteristic.setValue(DataByteArray.from(0x60))
delay(STANDARD_DELAY)
batteryLevelCharacteristic.setValue(byteArrayOf(0x5F))
batteryLevelCharacteristic.setValue(DataByteArray.from(0x5F))
delay(STANDARD_DELAY)
}
}

View File

@@ -31,7 +31,6 @@
package no.nordicsemi.android.gls.main.view
import android.util.Log
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
@@ -43,15 +42,14 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.gls.R
import no.nordicsemi.android.gls.main.viewmodel.GLSViewModel
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.ui.view.NavigateUpButton
import no.nordicsemi.android.ui.view.ProfileAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun GLSScreen() {
val viewModel: GLSViewModel = hiltViewModel()

View File

@@ -49,7 +49,7 @@ import kotlinx.coroutines.launch
import no.nordicsemi.android.analytics.AppAnalytics
import no.nordicsemi.android.analytics.Profile
import no.nordicsemi.android.analytics.ProfileConnectedEvent
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.navigation.NavigationResult
import no.nordicsemi.android.common.navigation.Navigator
import no.nordicsemi.android.gls.GlsDetailsDestinationId
@@ -60,11 +60,10 @@ import no.nordicsemi.android.gls.main.view.GLSViewState
import no.nordicsemi.android.gls.main.view.OnGLSRecordClick
import no.nordicsemi.android.gls.main.view.OnWorkingModeSelected
import no.nordicsemi.android.gls.main.view.OpenLoggerEvent
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient
import no.nordicsemi.android.kotlin.ble.client.main.connect
import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt
import no.nordicsemi.android.kotlin.ble.client.main.errors.GattOperationException
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -107,11 +106,11 @@ internal class GLSViewModel @Inject constructor(
private val loggerFactory: NordicLoggerFactory
) : ViewModel() {
internal lateinit var client: BleGattClient
private lateinit var logger: BlekLoggerAndLauncher
internal lateinit var client: ClientBleGatt
private lateinit var logger: BleLoggerAndLauncher
private lateinit var glucoseMeasurementCharacteristic: BleGattCharacteristic
private lateinit var recordAccessControlPointCharacteristic: BleGattCharacteristic
private lateinit var glucoseMeasurementCharacteristic: ClientBleGattCharacteristic
private lateinit var recordAccessControlPointCharacteristic: ClientBleGattCharacteristic
private val _state = MutableStateFlow(GLSViewState())
val state = _state.asStateFlow()
@@ -170,7 +169,7 @@ internal class GLSViewModel @Inject constructor(
logger = loggerFactory.createNordicLogger(context, stringConst.APP_NAME, "GLS", device.address)
client = device.connect(context, logger = logger)
client = ClientBleGatt.connect(context, device, logger = logger)
client.waitForBonding()
@@ -184,11 +183,12 @@ internal class GLSViewModel @Inject constructor(
return@launch
}
client.discoverServices()
.filterNotNull()
.onEach { configureGatt(it) }
.catch { onMissingServices() }
.launchIn(viewModelScope)
try {
val services = client.discoverServices()
configureGatt(services)
} catch (e: Exception) {
onMissingServices()
}
}
private fun onMissingServices() {
@@ -202,7 +202,7 @@ internal class GLSViewModel @Inject constructor(
}
}
private suspend fun configureGatt(services: BleGattServices) {
private suspend fun configureGatt(services: ClientBleGattServices) {
val glsService = services.findService(GLS_SERVICE_UUID)!!
glucoseMeasurementCharacteristic = glsService.findCharacteristic(GLUCOSE_MEASUREMENT_CHARACTERISTIC)!!
recordAccessControlPointCharacteristic = glsService.findCharacteristic(RACP_CHARACTERISTIC)!!
@@ -268,11 +268,11 @@ internal class GLSViewModel @Inject constructor(
try {
if (state.value.glsServiceData.records.isNotEmpty()) {
recordAccessControlPointCharacteristic.write(
RecordAccessControlPointInputParser.reportStoredRecordsGreaterThenOrEqualTo(highestSequenceNumber).value
RecordAccessControlPointInputParser.reportStoredRecordsGreaterThenOrEqualTo(highestSequenceNumber)
)
} else {
recordAccessControlPointCharacteristic.write(
RecordAccessControlPointInputParser.reportAllStoredRecords().value
RecordAccessControlPointInputParser.reportAllStoredRecords()
)
}
} catch (e: GattOperationException) {
@@ -298,7 +298,7 @@ internal class GLSViewModel @Inject constructor(
clear()
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.PENDING)
try {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportLastStoredRecord().value)
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportLastStoredRecord())
} catch (e: Exception) {
e.printStackTrace()
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.FAILED)
@@ -309,7 +309,7 @@ internal class GLSViewModel @Inject constructor(
clear()
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.PENDING)
try {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportFirstStoredRecord().value)
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportFirstStoredRecord())
} catch (e: Exception) {
e.printStackTrace()
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.FAILED)
@@ -320,7 +320,7 @@ internal class GLSViewModel @Inject constructor(
clear()
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.PENDING)
try {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords().value)
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords())
} catch (e: Exception) {
e.printStackTrace()
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.FAILED)

View File

@@ -54,7 +54,7 @@ dependencies {
implementation(libs.nordic.ble.common)
implementation(libs.nordic.ble.ktx)
implementation(libs.nordic.navigation)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.uilogger)
implementation(libs.nordic.core)

View File

@@ -38,8 +38,8 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import no.nordicsemi.android.common.core.simpleSharedFlow
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.logger.DefaultBleLogger
import no.nordicsemi.android.hrs.data.HRSServiceData
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
@@ -58,7 +58,7 @@ class HRSRepository @Inject constructor(
private val serviceManager: ServiceManager,
private val stringConst: StringConst
) {
private var logger: BlekLoggerAndLauncher? = null
private var logger: BleLoggerAndLauncher? = null
private val _data = MutableStateFlow(HRSServiceData())
internal val data = _data.asStateFlow()
@@ -86,7 +86,7 @@ class HRSRepository @Inject constructor(
private fun shouldClean() = !isOnScreen && !isServiceRunning
fun launch(device: ServerDevice) {
logger = NordicBlekLogger.create(context, stringConst.APP_NAME, "HRS", device.address)
logger = DefaultBleLogger.create(context, stringConst.APP_NAME, "HRS", device.address)
_data.value = _data.value.copy(deviceName = device.name)
serviceManager.startService(HRSService::class.java, device)
}

View File

@@ -41,9 +41,8 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient
import no.nordicsemi.android.kotlin.ble.client.main.connect
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -69,7 +68,7 @@ internal class HRSService : NotificationService() {
@Inject
lateinit var repository: HRSRepository
private lateinit var client: BleGattClient
private lateinit var client: ClientBleGatt
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
@@ -88,7 +87,7 @@ internal class HRSService : NotificationService() {
}
private fun startGattClient(device: ServerDevice) = lifecycleScope.launch {
client = device.connect(this@HRSService, logger = { p, s -> repository.log(p, s) })
client = ClientBleGatt.connect(this@HRSService, device, logger = { p, s -> repository.log(p, s) })
client.waitForBonding()
@@ -102,14 +101,15 @@ internal class HRSService : NotificationService() {
return@launch
}
client.discoverServices()
.filterNotNull()
.onEach { configureGatt(it) }
.catch { repository.onMissingServices() }
.launchIn(lifecycleScope)
try {
val services = client.discoverServices()
configureGatt(services)
} catch (e: Exception) {
repository.onMissingServices()
}
}
private suspend fun configureGatt(services: BleGattServices) {
private suspend fun configureGatt(services: ClientBleGattServices) {
val hrsService = services.findService(HRS_SERVICE_UUID)!!
val hrsMeasurementCharacteristic = hrsService.findCharacteristic(HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID)!!
val bodySensorLocationCharacteristic = hrsService.findCharacteristic(BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID)!!

View File

@@ -42,15 +42,14 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.hrs.R
import no.nordicsemi.android.hrs.viewmodel.HRSViewModel
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.ui.view.NavigateUpButton
import no.nordicsemi.android.ui.view.ProfileAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HRSScreen() {
val viewModel: HRSViewModel = hiltViewModel()

View File

@@ -52,7 +52,7 @@ dependencies {
implementation(libs.nordic.ble.ktx)
implementation(libs.nordic.theme)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.navigation)
implementation(libs.nordic.uilogger)
implementation(libs.nordic.core)

View File

@@ -38,8 +38,8 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import no.nordicsemi.android.common.core.simpleSharedFlow
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.logger.DefaultBleLogger
import no.nordicsemi.android.hts.data.HTSServiceData
import no.nordicsemi.android.hts.view.TemperatureUnit
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
@@ -59,7 +59,7 @@ class HTSRepository @Inject constructor(
private val serviceManager: ServiceManager,
private val stringConst: StringConst
) {
private var logger: BlekLoggerAndLauncher? = null
private var logger: BleLoggerAndLauncher? = null
private val _data = MutableStateFlow(HTSServiceData())
internal val data = _data.asStateFlow()
@@ -88,7 +88,7 @@ class HTSRepository @Inject constructor(
fun launch(device: ServerDevice) {
_data.value = _data.value.copy(deviceName = device.name)
logger = NordicBlekLogger.create(context, stringConst.APP_NAME, "HTS", device.address)
logger = DefaultBleLogger.create(context, stringConst.APP_NAME, "HTS", device.address)
serviceManager.startService(HTSService::class.java, device)
}

View File

@@ -41,9 +41,8 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient
import no.nordicsemi.android.kotlin.ble.client.main.connect
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -67,7 +66,7 @@ internal class HTSService : NotificationService() {
@Inject
lateinit var repository: HTSRepository
private lateinit var client: BleGattClient
private lateinit var client: ClientBleGatt
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
@@ -86,7 +85,7 @@ internal class HTSService : NotificationService() {
}
private fun startGattClient(device: ServerDevice) = lifecycleScope.launch {
client = device.connect(this@HTSService, logger = { p, s -> repository.log(p, s) })
client = ClientBleGatt.connect(this@HTSService, device, logger = { p, s -> repository.log(p, s) })
client.connectionStateWithStatus
.onEach { repository.onConnectionStateChanged(it) }
@@ -98,14 +97,15 @@ internal class HTSService : NotificationService() {
return@launch
}
client.discoverServices()
.filterNotNull()
.onEach { configureGatt(it) }
.catch { repository.onMissingServices() }
.launchIn(lifecycleScope)
try {
val services = client.discoverServices()
configureGatt(services)
} catch (e: Exception) {
repository.onMissingServices()
}
}
private suspend fun configureGatt(services: BleGattServices) {
private suspend fun configureGatt(services: ClientBleGattServices) {
val htsService = services.findService(HTS_SERVICE_UUID)!!
val htsMeasurementCharacteristic = htsService.findCharacteristic(HTS_MEASUREMENT_CHARACTERISTIC_UUID)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!

View File

@@ -35,22 +35,20 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.hts.R
import no.nordicsemi.android.hts.viewmodel.HTSViewModel
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.ui.view.NavigateUpButton
import no.nordicsemi.android.ui.view.ProfileAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HTSScreen() {
val viewModel: HTSViewModel = hiltViewModel()

View File

@@ -53,7 +53,7 @@ dependencies {
implementation(libs.nordic.ble.ktx)
implementation(libs.nordic.theme)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.navigation)
implementation(libs.nordic.uilogger)
implementation(libs.nordic.core)

View File

@@ -38,8 +38,8 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import no.nordicsemi.android.common.core.simpleSharedFlow
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.logger.DefaultBleLogger
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -58,7 +58,7 @@ class PRXRepository @Inject internal constructor(
private val serviceManager: ServiceManager,
private val stringConst: StringConst
) {
private var logger: BlekLoggerAndLauncher? = null
private var logger: BleLoggerAndLauncher? = null
private val _data = MutableStateFlow(PRXServiceData())
internal val data = _data.asStateFlow()
@@ -89,7 +89,7 @@ class PRXRepository @Inject internal constructor(
private fun shouldClean() = !isOnScreen && !isServiceRunning
fun launch(device: ServerDevice) {
logger = NordicBlekLogger.create(context, stringConst.APP_NAME, "PRX", device.address)
logger = DefaultBleLogger.create(context, stringConst.APP_NAME, "PRX", device.address)
_data.value = _data.value.copy(deviceName = device.name)
serviceManager.startService(PRXService::class.java, device)
}

View File

@@ -41,12 +41,9 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient
import no.nordicsemi.android.kotlin.ble.client.main.connect
import no.nordicsemi.android.kotlin.ble.client.main.errors.GattOperationException
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectOptions
import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus
@@ -58,14 +55,13 @@ import no.nordicsemi.android.kotlin.ble.profile.battery.BatteryLevelParser
import no.nordicsemi.android.kotlin.ble.profile.prx.AlarmLevel
import no.nordicsemi.android.kotlin.ble.profile.prx.AlarmLevelParser
import no.nordicsemi.android.kotlin.ble.profile.prx.AlertLevelInputParser
import no.nordicsemi.android.kotlin.ble.server.main.BleGattServer
import no.nordicsemi.android.kotlin.ble.server.main.service.BleGattServerServiceType
import no.nordicsemi.android.kotlin.ble.server.main.service.BleServerGattCharacteristicConfig
import no.nordicsemi.android.kotlin.ble.server.main.service.BleServerGattServiceConfig
import no.nordicsemi.android.kotlin.ble.server.main.service.BluetoothGattServerConnection
import no.nordicsemi.android.kotlin.ble.server.main.ServerBleGatt
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBleGattCharacteristicConfig
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBleGattServiceConfig
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBleGattServiceType
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBluetoothGattConnection
import no.nordicsemi.android.service.DEVICE_DATA
import no.nordicsemi.android.service.NotificationService
import no.nordicsemi.android.ui.view.StringConst
import java.util.*
import javax.inject.Inject
@@ -84,10 +80,10 @@ internal class PRXService : NotificationService() {
@Inject
lateinit var repository: PRXRepository
private lateinit var client: BleGattClient
private lateinit var server: BleGattServer
private lateinit var client: ClientBleGatt
private lateinit var server: ServerBleGatt
private var alertLevelCharacteristic: BleGattCharacteristic? = null
private var alertLevelCharacteristic: ClientBleGattCharacteristic? = null
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
@@ -106,41 +102,41 @@ internal class PRXService : NotificationService() {
}
private fun startServer(device: ServerDevice) = lifecycleScope.launch {
val alertLevelCharacteristic = BleServerGattCharacteristicConfig(
val alertLevelCharacteristic = ServerBleGattCharacteristicConfig(
uuid = ALERT_LEVEL_CHARACTERISTIC_UUID,
properties = listOf(BleGattProperty.PROPERTY_WRITE_NO_RESPONSE),
permissions = listOf(BleGattPermission.PERMISSION_WRITE)
)
val prxServiceConfig = BleServerGattServiceConfig(
val prxServiceConfig = ServerBleGattServiceConfig(
uuid = PRX_SERVICE_UUID,
type = BleGattServerServiceType.SERVICE_TYPE_PRIMARY,
type = ServerBleGattServiceType.SERVICE_TYPE_PRIMARY,
characteristicConfigs = listOf(alertLevelCharacteristic)
)
val linkLossCharacteristic = BleServerGattCharacteristicConfig(
val linkLossCharacteristic = ServerBleGattCharacteristicConfig(
uuid = ALERT_LEVEL_CHARACTERISTIC_UUID,
properties = listOf(BleGattProperty.PROPERTY_WRITE, BleGattProperty.PROPERTY_READ),
permissions = listOf(BleGattPermission.PERMISSION_WRITE, BleGattPermission.PERMISSION_READ),
initialValue = AlertLevelInputParser.parse(AlarmLevel.HIGH)
)
val linkLossServiceConfig = BleServerGattServiceConfig(
val linkLossServiceConfig = ServerBleGattServiceConfig(
uuid = LINK_LOSS_SERVICE_UUID,
type = BleGattServerServiceType.SERVICE_TYPE_PRIMARY,
type =ServerBleGattServiceType.SERVICE_TYPE_PRIMARY,
characteristicConfigs = listOf(linkLossCharacteristic)
)
server = BleGattServer.create(this@PRXService, prxServiceConfig, linkLossServiceConfig)
server = ServerBleGatt.create(this@PRXService, prxServiceConfig, linkLossServiceConfig)
//Order is important. We don't want to connect before services have been added to the server.
startGattClient(device)
server.onNewConnection
.onEach { setUpServerConnection(it.second) }
.onEach { setUpServerConnection(it) }
.launchIn(lifecycleScope)
}
private fun setUpServerConnection(connection: BluetoothGattServerConnection) {
private fun setUpServerConnection(connection: ServerBluetoothGattConnection) {
val prxService = connection.services.findService(PRX_SERVICE_UUID)!!
val linkLossService = connection.services.findService(LINK_LOSS_SERVICE_UUID)!!
@@ -159,8 +155,9 @@ internal class PRXService : NotificationService() {
}
private fun startGattClient(device: ServerDevice) = lifecycleScope.launch {
client = device.connect(
client = ClientBleGatt.connect(
this@PRXService,
device,
logger = { p, s -> repository.log(p, s) },
options = BleGattConnectOptions(autoConnect = true)
)
@@ -177,18 +174,19 @@ internal class PRXService : NotificationService() {
return@launch
}
client.discoverServices()
.filterNotNull()
.onEach { configureGatt(it) }
.catch { repository.onMissingServices() }
.launchIn(lifecycleScope)
try {
val services = client.discoverServices()
configureGatt(services)
} catch (e: Exception) {
repository.onMissingServices()
}
repository.remoteAlarmLevel
.onEach { writeAlertLevel(it) }
.launchIn(lifecycleScope)
}
private suspend fun configureGatt(services: BleGattServices) {
private suspend fun configureGatt(services: ClientBleGattServices) {
val prxService = services.findService(PRX_SERVICE_UUID)!!
alertLevelCharacteristic = prxService.findCharacteristic(ALERT_LEVEL_CHARACTERISTIC_UUID)!!
val linkLossService = services.findService(LINK_LOSS_SERVICE_UUID)!!

View File

@@ -42,15 +42,14 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.prx.R
import no.nordicsemi.android.prx.viewmodel.PRXViewModel
import no.nordicsemi.android.ui.view.NavigateUpButton
import no.nordicsemi.android.ui.view.ProfileAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PRXScreen() {
val viewModel: PRXViewModel = hiltViewModel()

View File

@@ -52,7 +52,7 @@ dependencies {
implementation(libs.nordic.ble.ktx)
implementation(libs.nordic.theme)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.nordic.navigation)
implementation(libs.nordic.uilogger)
implementation(libs.nordic.core)

View File

@@ -38,8 +38,8 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import no.nordicsemi.android.common.core.simpleSharedFlow
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.logger.DefaultBleLogger
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -58,7 +58,7 @@ class RSCSRepository @Inject constructor(
private val serviceManager: ServiceManager,
private val stringConst: StringConst
) {
private var logger: BlekLoggerAndLauncher? = null
private var logger: BleLoggerAndLauncher? = null
private val _data = MutableStateFlow(RSCSServiceData())
internal val data = _data.asStateFlow()
@@ -86,7 +86,7 @@ class RSCSRepository @Inject constructor(
private fun shouldClean() = !isOnScreen && !isServiceRunning
fun launch(device: ServerDevice) {
logger = NordicBlekLogger.create(context, stringConst.APP_NAME, "RSCS", device.address)
logger = DefaultBleLogger.create(context, stringConst.APP_NAME, "RSCS", device.address)
_data.value = _data.value.copy(deviceName = device.name)
serviceManager.startService(RSCSService::class.java, device)
}

View File

@@ -41,10 +41,8 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient
import no.nordicsemi.android.kotlin.ble.client.main.connect
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -52,7 +50,6 @@ import no.nordicsemi.android.kotlin.ble.profile.battery.BatteryLevelParser
import no.nordicsemi.android.kotlin.ble.profile.rscs.RSCSDataParser
import no.nordicsemi.android.service.DEVICE_DATA
import no.nordicsemi.android.service.NotificationService
import no.nordicsemi.android.ui.view.StringConst
import java.util.*
import javax.inject.Inject
@@ -69,7 +66,7 @@ internal class RSCSService : NotificationService() {
@Inject
lateinit var repository: RSCSRepository
private lateinit var client: BleGattClient
private lateinit var client: ClientBleGatt
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
@@ -88,7 +85,7 @@ internal class RSCSService : NotificationService() {
}
private fun startGattClient(device: ServerDevice) = lifecycleScope.launch {
client = device.connect(this@RSCSService, logger = { p, s -> repository.log(p, s) })
client = ClientBleGatt.connect(this@RSCSService, device, logger = { p, s -> repository.log(p, s) })
client.connectionStateWithStatus
.onEach { repository.onConnectionStateChanged(it) }
@@ -100,14 +97,15 @@ internal class RSCSService : NotificationService() {
return@launch
}
client.discoverServices()
.filterNotNull()
.onEach { configureGatt(it) }
.catch { repository.onMissingServices() }
.launchIn(lifecycleScope)
try {
val services = client.discoverServices()
configureGatt(services)
} catch (e: Exception) {
repository.onMissingServices()
}
}
private suspend fun configureGatt(services: BleGattServices) {
private suspend fun configureGatt(services: ClientBleGattServices) {
val rscsService = services.findService(RSCS_SERVICE_UUID)!!
val rscsMeasurementCharacteristic = rscsService.findCharacteristic(RSC_MEASUREMENT_CHARACTERISTIC_UUID)!!
val batteryService = services.findService(BATTERY_SERVICE_UUID)!!

View File

@@ -35,22 +35,20 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.rscs.R
import no.nordicsemi.android.rscs.viewmodel.RSCSViewModel
import no.nordicsemi.android.ui.view.NavigateUpButton
import no.nordicsemi.android.ui.view.ProfileAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun RSCSScreen() {
val viewModel: RSCSViewModel = hiltViewModel()

View File

@@ -72,10 +72,10 @@ dependencies {
implementation(libs.nordic.ble.ktx)
implementation(libs.nordic.theme)
implementation(libs.nordic.uiscanner)
implementation(libs.nordic.navigation)
implementation(libs.nordic.uilogger)
implementation(libs.nordic.core)
implementation(libs.nordic.blek.uiscanner)
implementation(libs.androidx.dataStore.core)
implementation(libs.androidx.dataStore.preferences)
@@ -86,6 +86,7 @@ dependencies {
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.lifecycle.service)
implementation(libs.okio)
// For Robolectric tests.
testImplementation("com.google.dagger:hilt-android-testing:2.44")

View File

@@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import no.nordicsemi.android.common.core.simpleSharedFlow
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
@@ -65,7 +65,7 @@ class UARTRepository @Inject internal constructor(
private val stringConst: StringConst,
private val loggerFactory: NordicLoggerFactory
) {
private var logger: BlekLoggerAndLauncher? = null
private var logger: BleLoggerAndLauncher? = null
private val _data = MutableStateFlow(UARTServiceData())
internal val data = _data.asStateFlow()

View File

@@ -41,10 +41,10 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient
import no.nordicsemi.android.kotlin.ble.client.main.connect
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
import no.nordicsemi.android.common.core.DataByteArray
import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.BleGattProperty
import no.nordicsemi.android.kotlin.ble.core.data.BleWriteType
@@ -69,7 +69,7 @@ internal class UARTService : NotificationService() {
@Inject
lateinit var repository: UARTRepository
private lateinit var client: BleGattClient
private lateinit var client: ClientBleGatt
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
@@ -88,7 +88,7 @@ internal class UARTService : NotificationService() {
}
private fun startGattClient(device: ServerDevice) = lifecycleScope.launch {
client = device.connect(this@UARTService, logger = { p, s -> repository.log(p, s) })
client = ClientBleGatt.connect(this@UARTService, device, logger = { p, s -> repository.log(p, s) })
client.requestMtu(Mtu.max)
@@ -101,14 +101,15 @@ internal class UARTService : NotificationService() {
return@launch
}
client.discoverServices()
.filterNotNull()
.onEach { configureGatt(it) }
.catch { repository.onMissingServices() }
.launchIn(lifecycleScope)
try {
val services = client.discoverServices()
configureGatt(services)
} catch (e: Exception) {
repository.onMissingServices()
}
}
private suspend fun configureGatt(services: BleGattServices) {
private suspend fun configureGatt(services: ClientBleGattServices) {
val uartService = services.findService(UART_SERVICE_UUID)!!
val rxCharacteristic = uartService.findCharacteristic(UART_RX_CHARACTERISTIC_UUID)!!
val txCharacteristic = uartService.findCharacteristic(UART_TX_CHARACTERISTIC_UUID)!!
@@ -122,19 +123,19 @@ internal class UARTService : NotificationService() {
?.launchIn(lifecycleScope)
txCharacteristic.getNotifications()
.onEach { repository.onNewMessageReceived(String(it)) }
.onEach { repository.log(10, "Received: ${String(it)}") }
.onEach { repository.onNewMessageReceived(String(it.value)) }
.onEach { repository.log(10, "Received: ${String(it.value)}") }
.catch { it.printStackTrace() }
.launchIn(lifecycleScope)
repository.command
.onEach { rxCharacteristic.splitWrite(it.toByteArray(), getWriteType(rxCharacteristic)) }
.onEach { rxCharacteristic.splitWrite(DataByteArray.from(it), getWriteType(rxCharacteristic)) }
.onEach { repository.onNewMessageSent(it) }
.onEach { repository.log(10, "Sent: $it") }
.launchIn(lifecycleScope)
}
private fun getWriteType(characteristic: BleGattCharacteristic): BleWriteType {
private fun getWriteType(characteristic: ClientBleGattCharacteristic): BleWriteType {
return if (characteristic.properties.contains(BleGattProperty.PROPERTY_WRITE)) {
BleWriteType.DEFAULT
} else {

View File

@@ -48,16 +48,14 @@ import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.common.theme.view.PagerView
import no.nordicsemi.android.common.theme.view.PagerViewEntity
import no.nordicsemi.android.common.theme.view.PagerViewItem
import no.nordicsemi.android.common.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView
import no.nordicsemi.android.common.ui.scanner.view.Reason
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.uart.R
import no.nordicsemi.android.uart.viewmodel.UARTViewModel
import no.nordicsemi.android.ui.view.NavigateUpButton
import no.nordicsemi.android.ui.view.ProfileAppBar
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceConnectingView
import no.nordicsemi.android.kotlin.ble.ui.scanner.view.DeviceDisconnectedView
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun UARTScreen() {
val viewModel: UARTViewModel = hiltViewModel()

View File

@@ -5,7 +5,7 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.components.SingletonComponent
import dagger.hilt.testing.TestInstallIn
import no.nordicsemi.android.common.logger.BlekLoggerAndLauncher
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.ui.view.NordicLoggerFactory
import no.nordicsemi.android.ui.view.NordicLoggerFactoryHiltModule
@@ -24,8 +24,8 @@ class NordicLoggerFactoryTestModule {
profile: String?,
key: String,
name: String?,
): BlekLoggerAndLauncher {
return object : BlekLoggerAndLauncher {
): BleLoggerAndLauncher {
return object : BleLoggerAndLauncher {
override fun launch() {
}

View File

@@ -24,16 +24,16 @@ import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import no.nordicsemi.android.analytics.AppAnalytics
import no.nordicsemi.android.common.logger.NordicBlekLogger
import no.nordicsemi.android.common.core.ApplicationScope
import no.nordicsemi.android.common.logger.BleLoggerAndLauncher
import no.nordicsemi.android.common.logger.DefaultBleLogger
import no.nordicsemi.android.common.navigation.NavigationResult
import no.nordicsemi.android.common.navigation.Navigator
import no.nordicsemi.android.common.navigation.di.NavigationModule
import no.nordicsemi.android.kotlin.ble.client.main.ClientScope
import no.nordicsemi.android.kotlin.ble.core.MockServerDevice
import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
import no.nordicsemi.android.kotlin.ble.server.main.ServerScope
import no.nordicsemi.android.uart.data.UARTPersistentDataSource
import no.nordicsemi.android.uart.repository.UARTRepository
import no.nordicsemi.android.uart.view.DisconnectEvent
@@ -84,7 +84,7 @@ internal class UARTViewModelTest {
lateinit var context: Context
@RelaxedMockK
lateinit var logger: NordicBlekLogger
lateinit var logger: BleLoggerAndLauncher
@Inject
lateinit var repository: UARTRepository
@@ -119,16 +119,14 @@ internal class UARTViewModelTest {
profile: String?,
key: String,
name: String?,
): NordicBlekLogger {
): BleLoggerAndLauncher {
return logger
}
})
runBlocking {
mockkStatic("no.nordicsemi.android.kotlin.ble.client.main.ClientScopeKt")
every { ClientScope } returns CoroutineScope(UnconfinedTestDispatcher())
mockkStatic("no.nordicsemi.android.kotlin.ble.server.main.ServerScopeKt")
every { ServerScope } returns CoroutineScope(UnconfinedTestDispatcher())
mockkStatic("no.nordicsemi.android.common.core.ApplicationScopeKt")
every { ApplicationScope } returns CoroutineScope(UnconfinedTestDispatcher())
every { stringConst.APP_NAME } returns "Test"
uartServer = UartServer(CoroutineScope(UnconfinedTestDispatcher()))
@@ -138,8 +136,8 @@ internal class UARTViewModelTest {
@Before
fun prepareLogger() {
mockkObject(NordicBlekLogger.Companion)
every { NordicBlekLogger.create(any(), any(), any(), any()) } returns mockk()
mockkObject(DefaultBleLogger.Companion)
every { DefaultBleLogger.create(any(), any(), any(), any()) } returns mockk()
}
@Test

30
renovate.json Normal file
View File

@@ -0,0 +1,30 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
"group:all",
":dependencyDashboard",
"schedule:daily"
],
"commitMessageExtra": "{{{currentValue}}} to {{#if isPinDigest}}{{{newDigestShort}}}{{else}}{{#if isMajor}}{{prettyNewMajor}}{{else}}{{#if isSingleVersion}}{{prettyNewVersion}}{{else}}{{#if newValue}}{{{newValue}}}{{else}}{{{newDigestShort}}}{{/if}}{{/if}}{{/if}}{{/if}}",
"packageRules": [
{
"matchPackagePatterns": [
"androidx.compose.compiler:compiler"
],
"groupName": "kotlin"
},
{
"matchPackagePatterns": [
"org.jetbrains.kotlin.*"
],
"groupName": "kotlin"
},
{
"matchPackagePatterns": [
"com.google.devtools.ksp"
],
"groupName": "kotlin"
}
]
}

View File

@@ -48,11 +48,11 @@ dependencyResolutionManagement {
maven(url = "https://androidx.dev/storage/compose-compiler/repository/")
maven(url = "https://jitpack.io")
}
versionCatalogs {
create("libs") {
from("no.nordicsemi.android.gradle:version-catalog:1.5.8")
}
}
// versionCatalogs {
// create("libs") {
// from("no.nordicsemi.android.gradle:version-catalog:1.8.0")
// }
// }
}
rootProject.name = "Android-nRF-Toolbox"