@@ -10,6 +10,8 @@ import android.bluetooth.BluetoothProfile.STATE_CONNECTING
1010import android.bluetooth.BluetoothProfile.STATE_DISCONNECTED
1111import android.bluetooth.BluetoothProfile.STATE_DISCONNECTING
1212import com.juul.kable.ConnectionLostException
13+ import com.juul.kable.ObservationEvent
14+ import com.juul.kable.ObservationEvent.CharacteristicChange
1315import com.juul.kable.State
1416import com.juul.kable.State.Disconnected.Status.Cancelled
1517import com.juul.kable.State.Disconnected.Status.CentralDisconnected
@@ -35,25 +37,20 @@ import com.juul.kable.gatt.Response.OnServicesDiscovered
3537import com.juul.kable.logs.Logger
3638import com.juul.kable.logs.Logging
3739import com.juul.kable.logs.detail
40+ import com.juul.kable.toLazyCharacteristic
3841import kotlinx.coroutines.channels.Channel
3942import kotlinx.coroutines.channels.Channel.Factory.CONFLATED
40- import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
4143import kotlinx.coroutines.channels.SendChannel
4244import kotlinx.coroutines.channels.onFailure
43- import kotlinx.coroutines.flow.Flow
45+ import kotlinx.coroutines.flow.MutableSharedFlow
4446import kotlinx.coroutines.flow.MutableStateFlow
45- import kotlinx.coroutines.flow.consumeAsFlow
4647
4748private typealias DisconnectedAction = () -> Unit
4849
49- internal data class OnCharacteristicChanged (
50- val characteristic : BluetoothGattCharacteristic ,
51- val value : ByteArray ,
52- )
53-
5450internal class Callback (
5551 private val state : MutableStateFlow <State >,
5652 private val mtu : MutableStateFlow <Int ?>,
53+ private val onCharacteristicChanged : MutableSharedFlow <ObservationEvent <ByteArray >>,
5754 logging : Logging ,
5855 macAddress : String ,
5956) : BluetoothGattCallback() {
@@ -65,10 +62,6 @@ internal class Callback(
6562 disconnectedAction = action
6663 }
6764
68- private val _onCharacteristicChanged = Channel <OnCharacteristicChanged >(UNLIMITED )
69- val onCharacteristicChanged: Flow <OnCharacteristicChanged > =
70- _onCharacteristicChanged .consumeAsFlow()
71-
7265 val onResponse = Channel <Response >(CONFLATED )
7366 val onMtuChanged = Channel <OnMtuChanged >(CONFLATED )
7467
@@ -126,7 +119,6 @@ internal class Callback(
126119 }
127120
128121 if (newState == STATE_DISCONNECTING || newState == STATE_DISCONNECTED ) {
129- _onCharacteristicChanged .close()
130122 onResponse.close(ConnectionLostException ())
131123 }
132124 }
@@ -175,13 +167,13 @@ internal class Callback(
175167 characteristic : BluetoothGattCharacteristic ,
176168 ) {
177169 val value = characteristic.value
178- val event = OnCharacteristicChanged (characteristic, value)
179170 logger.debug {
180171 message = " onCharacteristicChanged"
181172 detail(characteristic)
182173 detail(value)
183174 }
184- _onCharacteristicChanged .trySendOrLog(event)
175+ val event = CharacteristicChange (characteristic.toLazyCharacteristic(), value)
176+ onCharacteristicChanged.tryEmitOrLog(event)
185177 }
186178
187179 override fun onDescriptorRead (
@@ -261,6 +253,14 @@ internal class Callback(
261253 }
262254 }
263255 }
256+
257+ private fun <E > MutableSharedFlow<E>.tryEmitOrLog (element : E ) {
258+ if (! tryEmit(element)) {
259+ logger.warn {
260+ message = " Callback was unable to deliver $element "
261+ }
262+ }
263+ }
264264}
265265
266266private val Int .disconnectedConnectionStatus: State .Disconnected .Status ?
0 commit comments