This commit is contained in:
Andrei Vereha 2021-06-27 01:38:34 +02:00
parent 8cc6ab260d
commit e1a996b3f7
2 changed files with 40 additions and 62 deletions

View file

@ -210,9 +210,10 @@ class OmnipodDashBleManagerImpl @Inject constructor(
emitter.onNext(PodEvent.BluetoothConnected(podAddress)) emitter.onNext(PodEvent.BluetoothConnected(podAddress))
emitter.onNext(PodEvent.Pairing) emitter.onNext(PodEvent.Pairing)
val mIO = conn.msgIO ?: throw ConnectException("Connection lost")
val ltkExchanger = LTKExchanger( val ltkExchanger = LTKExchanger(
aapsLogger, aapsLogger,
conn.msgIO, mIO,
ids, ids,
) )
val pairResult = ltkExchanger.negotiateLTK() val pairResult = ltkExchanger.negotiateLTK()

View file

@ -13,6 +13,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Ids
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ServiceDiscoverer import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ServiceDiscoverer
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.EnDecrypt import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.EnDecrypt
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ConnectException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.FailedToConnectException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.FailedToConnectException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.BleSendSuccess import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.BleSendSuccess
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType
@ -24,94 +25,67 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.Omn
sealed class ConnectionState sealed class ConnectionState
object Connecting: ConnectionState()
object Handshaking: ConnectionState()
object Connected : ConnectionState() object Connected : ConnectionState()
object NotConnected : ConnectionState() object NotConnected : ConnectionState()
class Connection( class Connection(
private val podDevice: BluetoothDevice, private val podDevice: BluetoothDevice,
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
context: Context, private val context: Context,
private val podState: OmnipodDashPodStateManager private val podState: OmnipodDashPodStateManager
) : DisconnectHandler { ) : DisconnectHandler {
private val incomingPackets = IncomingPackets() private val incomingPackets = IncomingPackets()
private val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets, this) private val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets, this)
private val gattConnection: BluetoothGatt private var gattConnection: BluetoothGatt? = null
private val bluetoothManager: BluetoothManager = private val bluetoothManager: BluetoothManager =
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
// The session is Synchronized because we can lose the connection right when establishing it @Volatile
var session: Session? = null var session: Session? = null
@Synchronized get
@Synchronized set
private val cmdBleIO: CmdBleIO
private val dataBleIO: DataBleIO
init { @Volatile
aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to ${podDevice.address}") var msgIO: MessageIO? = null
val autoConnect = false
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING
gattConnection = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE)
// OnDisconnect can be called after this point!!!
val state = waitForConnection(2)
if (state !is Connected) {
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
throw FailedToConnectException(podDevice.address)
}
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED
val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks)
val discoveredCharacteristics = discoverer.discoverServices()
cmdBleIO = CmdBleIO(
aapsLogger,
discoveredCharacteristics[CharacteristicType.CMD]!!,
incomingPackets
.cmdQueue,
gattConnection,
bleCommCallbacks
)
dataBleIO = DataBleIO(
aapsLogger,
discoveredCharacteristics[CharacteristicType.DATA]!!,
incomingPackets
.dataQueue,
gattConnection,
bleCommCallbacks
)
val sendResult = cmdBleIO.hello()
if (sendResult !is BleSendSuccess) {
throw FailedToConnectException("Could not send HELLO command to ${podDevice.address}")
}
cmdBleIO.readyToRead()
dataBleIO.readyToRead()
}
val msgIO = MessageIO(aapsLogger, cmdBleIO, dataBleIO)
fun connect(timeoutMultiplier: Int) { fun connect(timeoutMultiplier: Int) {
if (session != null) {
disconnect()
}
aapsLogger.debug("Connecting") aapsLogger.debug("Connecting")
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING
val autoConnect = false
if (!gattConnection.connect()) { val gatt = gattConnection ?:
podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE)
gattConnection = gatt
if (!gatt.connect()) {
throw FailedToConnectException("connect() returned false") throw FailedToConnectException("connect() returned false")
} }
// TODO: loop
if (waitForConnection(timeoutMultiplier) !is Connected) { if (waitForConnection(timeoutMultiplier) !is Connected) {
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
throw FailedToConnectException(podDevice.address) throw FailedToConnectException(podDevice.address)
} }
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED
val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks) val discoverer = ServiceDiscoverer(aapsLogger, gatt, bleCommCallbacks)
val discovered = discoverer.discoverServices() val discovered = discoverer.discoverServices()
dataBleIO.characteristic = discovered[CharacteristicType.DATA]!! val cmdBleIO = CmdBleIO(
cmdBleIO.characteristic = discovered[CharacteristicType.CMD]!! aapsLogger,
discovered[CharacteristicType.CMD]!!,
incomingPackets
.cmdQueue,
gatt,
bleCommCallbacks
)
val dataBleIO = DataBleIO(
aapsLogger,
discovered[CharacteristicType.DATA]!!,
incomingPackets
.dataQueue,
gatt,
bleCommCallbacks
)
msgIO = MessageIO(aapsLogger, cmdBleIO, dataBleIO)
// val ret = gattConnection.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH) // val ret = gattConnection.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH)
// aapsLogger.info(LTag.PUMPBTCOMM, "requestConnectionPriority: $ret") // aapsLogger.info(LTag.PUMPBTCOMM, "requestConnectionPriority: $ret")
cmdBleIO.hello() cmdBleIO.hello()
@ -123,9 +97,10 @@ class Connection(
aapsLogger.debug(LTag.PUMPBTCOMM, "Disconnecting") aapsLogger.debug(LTag.PUMPBTCOMM, "Disconnecting")
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
gattConnection.disconnect() gattConnection?.disconnect()
bleCommCallbacks.resetConnection() bleCommCallbacks.resetConnection()
session = null session = null
msgIO = null
} }
private fun waitForConnection(timeoutMultiplier: Int): ConnectionState { private fun waitForConnection(timeoutMultiplier: Int): ConnectionState {
@ -148,7 +123,9 @@ class Connection(
} }
fun establishSession(ltk: ByteArray, msgSeq: Byte, ids: Ids, eapSqn: ByteArray): EapSqn? { fun establishSession(ltk: ByteArray, msgSeq: Byte, ids: Ids, eapSqn: ByteArray): EapSqn? {
val eapAkaExchanger = SessionEstablisher(aapsLogger, msgIO, ltk, eapSqn, ids, msgSeq) val mIO = msgIO ?: throw ConnectException("Connection lost")
val eapAkaExchanger = SessionEstablisher(aapsLogger, mIO, ltk, eapSqn, ids, msgSeq)
return when (val keys = eapAkaExchanger.negotiateSessionKeys()) { return when (val keys = eapAkaExchanger.negotiateSessionKeys()) {
is SessionNegotiationResynchronization -> { is SessionNegotiationResynchronization -> {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
@ -168,7 +145,7 @@ class Connection(
keys.nonce, keys.nonce,
keys.ck keys.ck
) )
session = Session(aapsLogger, msgIO, ids, sessionKeys = keys, enDecrypt = enDecrypt) session = Session(aapsLogger, mIO, ids, sessionKeys = keys, enDecrypt = enDecrypt)
null null
} }
} }