Add experimental connection error message

This commit is contained in:
Sylwester Zielinski
2023-04-05 16:44:24 +02:00
parent 60c6e03559
commit 06ea417cb7
10 changed files with 26 additions and 24 deletions

View File

@@ -1,13 +1,13 @@
package no.nordicsemi.android.cgms.data
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState
import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus
import no.nordicsemi.android.kotlin.ble.profile.cgm.data.CGMRecord
import no.nordicsemi.android.kotlin.ble.profile.gls.data.RequestStatus
internal data class CGMServiceData(
val records: List<CGMRecordWithSequenceNumber> = emptyList(),
val batteryLevel: Int? = null,
val connectionState: GattConnectionState? = null,
val connectionState: GattConnectionStateWithStatus? = null,
val requestStatus: RequestStatus = RequestStatus.IDLE,
val deviceName: String? = null
)

View File

@@ -43,6 +43,7 @@ import no.nordicsemi.android.cgms.data.CGMServiceData
import no.nordicsemi.android.common.core.simpleSharedFlow
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
import no.nordicsemi.android.kotlin.ble.profile.gls.data.RequestStatus
import no.nordicsemi.android.service.DisconnectAndStopEvent
import no.nordicsemi.android.service.OpenLoggerEvent
@@ -68,7 +69,7 @@ class CGMRepository @Inject constructor(
private val _loggerEvent = simpleSharedFlow<OpenLoggerEvent>()
internal val loggerEvent = _loggerEvent.asSharedFlow()
val isRunning = data.map { it.connectionState == GattConnectionState.STATE_CONNECTED }
val isRunning = data.map { it.connectionState?.state == GattConnectionState.STATE_CONNECTED }
val hasRecords = data.value.records.isNotEmpty()
val highestSequenceNumber = data.value.records.maxOfOrNull { it.sequenceNumber } ?: -1
@@ -85,7 +86,7 @@ class CGMRepository @Inject constructor(
_command.tryEmit(command)
}
fun onConnectionStateChanged(connectionState: GattConnectionState?) {
fun onConnectionStateChanged(connectionState: GattConnectionStateWithStatus?) {
_data.value = _data.value.copy(connectionState = connectionState)
}

View File

@@ -50,6 +50,7 @@ import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattCharacteristi
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices
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
import no.nordicsemi.android.kotlin.ble.profile.battery.BatteryLevelParser
import no.nordicsemi.android.kotlin.ble.profile.cgm.CGMFeatureParser
import no.nordicsemi.android.kotlin.ble.profile.cgm.CGMMeasurementParser
@@ -139,7 +140,7 @@ internal class CGMService : NotificationService() {
.onEach { logger.launch() }
.launchIn(lifecycleScope)
client.connectionState
client.connectionStateWithStatus
.onEach { repository.onConnectionStateChanged(it) }
.filterNotNull()
.onEach { stopIfDisconnected(it) }
@@ -187,10 +188,10 @@ internal class CGMService : NotificationService() {
.mapNotNull { CGMSpecificOpsControlPointParser.parse(it) }
.onEach {
if (it.isOperationCompleted) {
if (it.requestCode == CGMOpCode.CGM_OP_CODE_START_SESSION) {
sessionStartTime = System.currentTimeMillis()
sessionStartTime = if (it.requestCode == CGMOpCode.CGM_OP_CODE_START_SESSION) {
System.currentTimeMillis()
} else {
sessionStartTime = 0
0
}
} else {
if (it.requestCode == CGMOpCode.CGM_OP_CODE_START_SESSION && it.errorCode == CGMErrorCode.CGM_ERROR_PROCEDURE_NOT_COMPLETED) {
@@ -298,8 +299,8 @@ internal class CGMService : NotificationService() {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords().value)
}
private fun stopIfDisconnected(connectionState: GattConnectionState) {
if (connectionState == GattConnectionState.STATE_DISCONNECTED) {
private fun stopIfDisconnected(connectionState: GattConnectionStateWithStatus) {
if (connectionState.state == GattConnectionState.STATE_DISCONNECTED) {
stopSelf()
}
}

View File

@@ -72,11 +72,11 @@ fun CGMScreen() {
.padding(16.dp)
.verticalScroll(rememberScrollState())
) {
when (state.connectionState) {
when (state.connectionState?.state) {
null,
GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) }
GattConnectionState.STATE_DISCONNECTED,
GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(Reason.UNKNOWN) {
GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.connectionState.status) {
NavigateUpButton(navigateUp)
}
GattConnectionState.STATE_CONNECTED -> CGMContentView(state) { viewModel.onEvent(it) }
@@ -88,7 +88,7 @@ fun CGMScreen() {
@Composable
private fun AppBar(state: CGMServiceData, navigateUp: () -> Unit, viewModel: CGMViewModel) {
if (state.deviceName?.isNotBlank() == true) {
if (state.connectionState == GattConnectionState.STATE_DISCONNECTING || state.connectionState == GattConnectionState.STATE_DISCONNECTED) {
if (state.connectionState?.state == GattConnectionState.STATE_DISCONNECTING || state.connectionState?.state == GattConnectionState.STATE_DISCONNECTED) {
LoggerBackIconAppBar(state.deviceName) { viewModel.onEvent(OpenLoggerEvent) }
} else {
LoggerIconAppBar(state.deviceName, navigateUp, { viewModel.onEvent(DisconnectEvent) }) {

View File

@@ -35,8 +35,6 @@ import android.os.ParcelUuid
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -76,7 +74,7 @@ internal class CGMViewModel @Inject constructor(
}
repository.data.onEach {
if (it.connectionState == GattConnectionState.STATE_CONNECTED) {
if (it.connectionState?.state == GattConnectionState.STATE_CONNECTED) {
analytics.logEvent(ProfileConnectedEvent(Profile.CGMS))
}
}.launchIn(viewModelScope)

View File

@@ -2,13 +2,14 @@ package no.nordicsemi.android.prx.data
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.profile.prx.AlarmLevel
data class PRXServiceData(
val localAlarmLevel: AlarmLevel = AlarmLevel.NONE,
val linkLossAlarmLevel: AlarmLevel = AlarmLevel.HIGH,
val batteryLevel: Int? = null,
val connectionState: GattConnectionState? = null,
val connectionState: GattConnectionStateWithStatus? = null,
val connectionStatus: BleGattConnectionStatus? = null,
val isRemoteAlarm: Boolean = false,
val deviceName: String? = null

View File

@@ -41,6 +41,7 @@ import no.nordicsemi.android.common.core.simpleSharedFlow
import no.nordicsemi.android.kotlin.ble.core.ServerDevice
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.profile.prx.AlarmLevel
import no.nordicsemi.android.prx.data.PRXServiceData
import no.nordicsemi.android.service.DisconnectAndStopEvent
@@ -68,7 +69,7 @@ class PRXRepository @Inject internal constructor(
private val _remoteAlarmLevel = simpleSharedFlow<AlarmLevel>()
internal val remoteAlarmLevel = _remoteAlarmLevel.asSharedFlow()
val isRunning = data.map { it.connectionState == GattConnectionState.STATE_CONNECTED }
val isRunning = data.map { it.connectionState?.state == GattConnectionState.STATE_CONNECTED }
fun launch(device: ServerDevice) {
serviceManager.startService(PRXService::class.java, device)
@@ -78,8 +79,8 @@ class PRXRepository @Inject internal constructor(
_data.value = _data.value.copy(deviceName = device.name)
}
fun onConnectionStateChanged(connection: Pair<GattConnectionState, BleGattConnectionStatus>) {
_data.value = _data.value.copy(connectionState = connection.first, connectionStatus = connection.second)
fun onConnectionStateChanged(connection: GattConnectionStateWithStatus) {
_data.value = _data.value.copy(connectionState = connection)
}
fun setLocalAlarmLevel(alarmLevel: AlarmLevel) {

View File

@@ -173,7 +173,7 @@ internal class PRXService : NotificationService() {
.filterNotNull()
.onEach { repository.onConnectionStateChanged(it) }
.filterNotNull()
.onEach { stopIfDisconnected(it.first, it.second) }
.onEach { stopIfDisconnected(it.state, it.status) }
.launchIn(lifecycleScope)
client.services

View File

@@ -71,11 +71,11 @@ fun PRXScreen() {
.padding(16.dp)
.verticalScroll(rememberScrollState())
) {
when (state.connectionState) {
when (state.connectionState?.state) {
null,
GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) }
GattConnectionState.STATE_DISCONNECTED,
GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(getReason(state.isLinkLossDisconnected)) {
GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.connectionState.status) {
NavigateUpButton(navigateUp)
}
GattConnectionState.STATE_CONNECTED -> ContentView(state) { viewModel.onEvent(it) }

View File

@@ -83,7 +83,7 @@ internal class PRXViewModel @Inject constructor(
alarmHandler.playAlarm(it.linkLossAlarmLevel)
}
if (it.connectionState == GattConnectionState.STATE_CONNECTED) {
if (it.connectionState?.state == GattConnectionState.STATE_CONNECTED) {
analytics.logEvent(ProfileConnectedEvent(Profile.PRX))
}
}.launchIn(viewModelScope)