Skip to content

Commit

Permalink
Update to the latest callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
weliem committed Oct 28, 2023
1 parent c24379e commit 06ed747
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 53 deletions.
6 changes: 4 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}

android {
namespace 'com.welie.blessedexample'
Expand Down
18 changes: 9 additions & 9 deletions blessed/build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'maven-publish'
plugins {
id 'com.android.library'
id 'maven-publish'
id 'org.jetbrains.kotlin.android'
}

android {

namespace 'com.welie.blessed'

compileSdk 34

defaultConfig {
Expand All @@ -23,12 +23,12 @@ android {
}

kotlinOptions {
jvmTarget = "17"
jvmTarget = "1.8"
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

Expand All @@ -39,7 +39,7 @@ dependencies {
implementation 'com.jakewharton.timber:timber:5.0.1'

testImplementation 'junit:junit:4.13.2'
testImplementation "org.robolectric:robolectric:4.5.1"
testImplementation "org.robolectric:robolectric:4.10.3"
testImplementation "org.mockito:mockito-core:3.8.0"
testImplementation 'androidx.test:core:1.5.0'
testImplementation "io.mockk:mockk:1.13.8"
Expand Down
88 changes: 73 additions & 15 deletions blessed/src/main/java/com/welie/blessed/BluetoothPeripheral.kt
Original file line number Diff line number Diff line change
Expand Up @@ -168,35 +168,67 @@ class BluetoothPeripheral internal constructor(
completedCommand()
}

override fun onDescriptorRead(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
override fun onDescriptorRead(
gatt: BluetoothGatt,
descriptor: BluetoothGattDescriptor,
status: Int,
value: ByteArray
) {
val gattStatus = GattStatus.fromValue(status)
if (gattStatus != GattStatus.SUCCESS) {
Logger.e(TAG, "reading descriptor <%s> failed for device '%s, status '%s'", descriptor.uuid, address, gattStatus)
}

val value = nonnullOf(descriptor.value)
val resultCallback = currentResultCallback
callbackScope.launch { resultCallback.onDescriptorRead(this@BluetoothPeripheral, value, descriptor, gattStatus) }
completedCommand()
}

override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
val value = nonnullOf(characteristic.value)
@Deprecated("Deprecated in Java")
override fun onDescriptorRead(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
if (Build.VERSION.SDK_INT < 33) {
onDescriptorRead(gatt, descriptor, status, nonnullOf(descriptor.value))
}
}

override fun onCharacteristicChanged(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
value: ByteArray
) {
callbackScope.launch { observeMap[characteristic]?.invoke(value) }
}

override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
@Deprecated("Deprecated in Java")
override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
if (Build.VERSION.SDK_INT < 33) {
onCharacteristicChanged(gatt, characteristic, nonnullOf(characteristic.value))
}
}

override fun onCharacteristicRead(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
value: ByteArray,
status: Int
) {
val gattStatus = GattStatus.fromValue(status)
if (gattStatus != GattStatus.SUCCESS) {
Logger.e(TAG, "read failed for characteristic <%s>, status '%s'", characteristic.uuid, gattStatus)
}

val value = nonnullOf(characteristic.value)
val resultCallback = currentResultCallback
callbackScope.launch { resultCallback.onCharacteristicRead(this@BluetoothPeripheral, value, characteristic, gattStatus) }
completedCommand()
}

@Deprecated("Deprecated in Java")
override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
if (Build.VERSION.SDK_INT < 33) {
onCharacteristicRead(gatt, characteristic, nonnullOf(characteristic.value), status)
}
}

override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
val gattStatus = GattStatus.fromValue(status)
if (gattStatus != GattStatus.SUCCESS) {
Expand Down Expand Up @@ -922,9 +954,9 @@ class BluetoothPeripheral internal constructor(
// See https://stackoverflow.com/questions/48216517/rxandroidble-write-only-sends-the-first-20b
Logger.w(TAG, "value byte array is longer than allowed by MTU, write will fail if peripheral does not support long writes")
}
characteristic.value = bytesToWrite
if (bluetoothGatt?.writeCharacteristic(characteristic) == true) {
Logger.d(TAG, "writing <%s> to characteristic <%s>", BluetoothBytesParser.bytes2String(bytesToWrite), characteristic.uuid)

if (internalWriteCharacteristic(characteristic, bytesToWrite, writeType)) {
Logger.d(TAG, "writing <%s> to characteristic <%s>", bytesToWrite.asHexString(), characteristic.uuid)
nrTries++
} else {
Logger.e(TAG, "writeCharacteristic failed for characteristic: %s", characteristic.uuid)
Expand All @@ -942,6 +974,24 @@ class BluetoothPeripheral internal constructor(
return value.size > currentMtu - 3 && writeType == WriteType.WITH_RESPONSE
}

private fun internalWriteCharacteristic(
characteristic: BluetoothGattCharacteristic,
value: ByteArray,
writeType: WriteType
): Boolean {
if (bluetoothGatt == null) return false

currentWriteBytes = value
return if (Build.VERSION.SDK_INT >= 33) {
val result = bluetoothGatt?.writeCharacteristic(characteristic, currentWriteBytes, writeType.writeType)
result == BluetoothStatusCodes.SUCCESS
} else {
characteristic.writeType = writeType.writeType
characteristic.value = value
bluetoothGatt!!.writeCharacteristic(characteristic)
}
}

suspend fun readDescriptor(descriptor: BluetoothGattDescriptor): ByteArray =
suspendCoroutine {
try {
Expand Down Expand Up @@ -1033,10 +1083,8 @@ class BluetoothPeripheral internal constructor(
return enqueue {
if (isConnected) {
currentResultCallback = resultCallback
currentWriteBytes = bytesToWrite
descriptor.value = bytesToWrite
if (bluetoothGatt?.writeDescriptor(descriptor) == true) {
Logger.d(TAG, "writing <%s> to descriptor <%s>", BluetoothBytesParser.bytes2String(bytesToWrite), descriptor.uuid)
if (internalWriteDescriptor(descriptor, bytesToWrite)) {
Logger.d(TAG, "writing <%s> to descriptor <%s>", bytesToWrite.asHexString(), descriptor.uuid)
nrTries++
} else {
Logger.e(TAG, "writeDescriptor failed for descriptor: %s", descriptor.uuid)
Expand All @@ -1050,6 +1098,17 @@ class BluetoothPeripheral internal constructor(
}
}

private fun internalWriteDescriptor(descriptor: BluetoothGattDescriptor, value: ByteArray): Boolean {
if (bluetoothGatt == null) return false
currentWriteBytes = value
return if (Build.VERSION.SDK_INT >= 33) {
val result = bluetoothGatt?.writeDescriptor(descriptor, value)
result == BluetoothStatusCodes.SUCCESS
} else {
descriptor.value = value
bluetoothGatt!!.writeDescriptor(descriptor)
}
}

suspend fun observe(characteristic: BluetoothGattCharacteristic, callback: (value: ByteArray) -> Unit): Boolean =
suspendCoroutine {
Expand Down Expand Up @@ -1156,8 +1215,7 @@ class BluetoothPeripheral internal constructor(
completedCommand()
} else {
currentWriteBytes = finalValue
descriptor.value = finalValue
if (bluetoothGatt?.writeDescriptor(descriptor) == true) {
if (internalWriteDescriptor(descriptor, finalValue)) {
nrTries++
} else {
Logger.e(TAG, "writeDescriptor failed for descriptor: %s", descriptor.uuid)
Expand Down
55 changes: 29 additions & 26 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.9.10'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:8.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
plugins {
id 'com.android.application' version '8.1.2' apply false
id 'com.android.library' version '8.1.2' apply false
id 'org.jetbrains.kotlin.android' version '1.9.10' apply false
}

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

task clean(type: Delete) {
delete rootProject.buildDir
}
//// Top-level build file where you can add configuration options common to all sub-projects/modules.
//
//buildscript {
// ext.kotlin_version = '1.9.10'
// repositories {
// google()
// mavenCentral()
// }
//
// dependencies {
// classpath 'com.android.tools.build:gradle:8.1.2'
// classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
//
// // NOTE: Do not place your application dependencies here; they belong
// // in the individual module build.gradle files
// }
//}
//
//allprojects {
// repositories {
// google()
// mavenCentral()
// maven { url 'https://jitpack.io' }
// }
//}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ org.gradle.jvmargs=-Xmx1536m
# 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
# org.gradle.parallel=true

kotlin.code.style=official

15 changes: 15 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}

include ':app', ':blessed'

0 comments on commit 06ed747

Please sign in to comment.