my now fixed nice bluetooth api works well

pull/8/head
geeksville 2020-01-23 23:05:15 -08:00
rodzic d05922f716
commit bf26f7293a
3 zmienionych plików z 22 dodań i 28 usunięć

Wyświetl plik

@ -88,7 +88,8 @@ dependencies {
// Add the Firebase SDK for Crashlytics.
implementation 'com.google.firebase:firebase-crashlytics:17.0.0-beta01'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
// alas implementation bug deep in the bowels when I tried it for my SyncBluetoothDevice class
// implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
// add SDKs for any other desired Firebase products
// https://firebase.google.com/docs/android/setup#available-libraries

Wyświetl plik

@ -10,12 +10,10 @@ import android.os.SystemClock
import android.widget.Toast
import androidx.core.app.JobIntentService
import com.geeksville.android.Logging
import kotlinx.coroutines.*
import java.io.IOException
import java.io.InputStream
import java.util.*
import java.util.zip.CRC32
import kotlin.coroutines.*
/**
* typical flow
@ -29,7 +27,7 @@ import kotlin.coroutines.*
* FIXME - broadcast when we found devices, made progress sending blocks or when the update is complete
* FIXME - make the user decide to start an update on a particular device
*/
class SoftwareUpdateService : JobIntentService(), Logging, CoroutineScope by MainScope() {
class SoftwareUpdateService : JobIntentService(), Logging {
private val bluetoothAdapter: BluetoothAdapter by lazy(LazyThreadSafetyMode.NONE) {
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
@ -41,8 +39,6 @@ class SoftwareUpdateService : JobIntentService(), Logging, CoroutineScope by Mai
fun startUpdate() {
info("starting update")
// FIXME, is this the right scope to use? I want it to block in the job queue
launch {
val sync = SyncBluetoothDevice(this@SoftwareUpdateService, device)
val firmwareStream = assets.open("firmware.bin")
@ -110,7 +106,6 @@ class SoftwareUpdateService : JobIntentService(), Logging, CoroutineScope by Mai
logAssert(updateResult == 0) // FIXME - handle this case
// FIXME perhaps ask device to reboot
}
}
@ -192,7 +187,6 @@ class SoftwareUpdateService : JobIntentService(), Logging, CoroutineScope by Mai
}
override fun onDestroy() {
cancel() // Stop the CoroutineScope
super.onDestroy()
// toast("All work complete")
}

Wyświetl plik

@ -4,10 +4,8 @@ import android.bluetooth.*
import android.content.Context
import com.geeksville.android.Logging
import java.io.IOException
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
import com.geeksville.concurrent.SyncContinuation
import com.geeksville.concurrent.suspend
/**
@ -19,13 +17,14 @@ import kotlin.coroutines.suspendCoroutine
*
* This class fixes the API by using coroutines to let you safely do a series of BTLE operations.
*/
class SyncBluetoothDevice(private val context: Context, private val device: BluetoothDevice) : Logging {
class SyncBluetoothDevice(private val context: Context, private val device: BluetoothDevice) :
Logging {
private var pendingServiceDesc: Continuation<Unit>? = null
private var pendingMtu: Continuation<kotlin.Int>? = null
private var pendingWriteC: Continuation<Unit>? = null
private var pendingReadC: Continuation<BluetoothGattCharacteristic>? = null
private var pendingConnect: Continuation<Unit>? = null
private var pendingServiceDesc: SyncContinuation<Unit>? = null
private var pendingMtu: SyncContinuation<kotlin.Int>? = null
private var pendingWriteC: SyncContinuation<Unit>? = null
private var pendingReadC: SyncContinuation<BluetoothGattCharacteristic>? = null
private var pendingConnect: SyncContinuation<Unit>? = null
private val gattCallback = object : BluetoothGattCallback() {
@ -37,7 +36,7 @@ class SyncBluetoothDevice(private val context: Context, private val device: Blue
info("new bluetooth connection state $newState")
when (newState) {
BluetoothProfile.STATE_CONNECTED -> {
if(pendingConnect != null) { // If someone was waiting to connect unblock them
if (pendingConnect != null) { // If someone was waiting to connect unblock them
pendingConnect!!.resume(Unit)
pendingConnect = null
}
@ -91,32 +90,32 @@ class SyncBluetoothDevice(private val context: Context, private val device: Blue
/// Users can access the GATT directly as needed
lateinit var gatt: BluetoothGatt
suspend fun connect() =
suspendCoroutine<Unit> { cont ->
fun connect() =
suspend<Unit> { cont ->
pendingConnect = cont
gatt = device.connectGatt(context, false, gattCallback)!!
}
suspend fun discoverServices() =
suspendCoroutine<Unit> { cont ->
fun discoverServices() =
suspend<Unit> { cont ->
pendingServiceDesc = cont
logAssert(gatt.discoverServices())
}
/// Returns the actual MTU size used
suspend fun requestMtu(len: Int): kotlin.Int = suspendCoroutine { cont ->
fun requestMtu(len: Int) = suspend<kotlin.Int> { cont ->
pendingMtu = cont
logAssert(gatt.requestMtu(len))
}
suspend fun writeCharacteristic(c: BluetoothGattCharacteristic) =
suspendCoroutine<Unit> { cont ->
fun writeCharacteristic(c: BluetoothGattCharacteristic) =
suspend<Unit> { cont ->
pendingWriteC = cont
logAssert(gatt.writeCharacteristic(c))
}
suspend fun readCharacteristic(c: BluetoothGattCharacteristic) =
suspendCoroutine<BluetoothGattCharacteristic> { cont ->
fun readCharacteristic(c: BluetoothGattCharacteristic) =
suspend<BluetoothGattCharacteristic> { cont ->
pendingReadC = cont
logAssert(gatt.readCharacteristic(c))
}