https://kotlinlang.org logo
#android
Title
# android
m

MartinZaubitzer

04/01/2020, 11:59 AM
Hi people, maybe someone can help me explain coroutines for my use case: I am developing a BLE communication protocol which includes messages that receive a custom answer from the peripheral. Now I would like to use coroutines and channels to make a queue of messages to send and only send the next message after a successful response. I am struggling to understand how I can await the result of the ble callback since it is not a function that returns anything. Thanks in advance!
g

gsala

04/01/2020, 12:45 PM
Are you tied to any Android BLE library? Or just using the framework?
m

MartinZaubitzer

04/01/2020, 12:46 PM
Nope I am just using the standard BLE framework.
g

gsala

04/01/2020, 12:47 PM
Is it a client-server pattern, where you write to a characteristic and the peripheral sends a notification ?
m

MartinZaubitzer

04/01/2020, 12:51 PM
Yes, but I was required to flip the roles, so the Android device is the server. This shouldn't really affect my issue/want I am trying to do, but quick rundown: Android opens a GATT sever, BLE device connects, pairs, and subscribes to notifications. Communication from Android to BLE Device is done via notifications. Communication from BLE Device to Android is done by writes. So I send a notification and expect the response in the onCharacteristicWriteRequest() callback.
What I have so far (I don’t know if correct/working):
Copy code
suspend fun sendMessageWithResponse(msg : ByteArray): ByteArray? {
        sendBleMsg(msg, DeviceUUID.toString())
        return withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
            receiveUpdate()
        }
    }

private suspend fun receiveUpdate(): ByteArray? =
        suspendCoroutine { cont ->
            object : BluetoothGattServerCallback {
               override fun onCharacteristicWriteRequest(
            device: BluetoothDevice?,
            requestId: Int,
            characteristic: BluetoothGattCharacteristic?,
            preparedWrite: Boolean,
            responseNeeded: Boolean,
            offset: Int,
            value: ByteArray?
        ) {
              if (characteristic != null) {
                when (characteristic.uuid) {
                    BycomProfile.buildUUIDfromBase(Profile.DATA_IN_CHAR) -> {
                       cont.resume(value)
                    }
                }
            }
          }
     }
}
g

gsala

04/01/2020, 2:53 PM
I'm dealing with similar concepts, but the phone being the server throws me off a bit. I don't think I can help much 😅
m

MartinZaubitzer

04/01/2020, 2:55 PM
That sounds good. In the end it doesn’t really matter. If you would be so kind and help/explain it to me with the standard BLE concept I can “translate” it to my case 😅
9 Views