diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt index 3847d0588c..b78aa5ecc5 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt @@ -36,5 +36,8 @@ data class Id(val address: ByteArray) { fun fromInt(v: Int): Id { return Id(ByteBuffer.allocate(4).putInt(v).array()) } + fun fromLong(v: Long): Id { + return Id(ByteBuffer.allocate(8).putLong(v).array().copyOfRange(4,8)) + } } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt index c14fc4e7bf..a7c50bff4e 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt @@ -2,11 +2,13 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice +import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothManager import android.bluetooth.BluetoothProfile import android.content.Context import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.pump.omnipod.dash.BuildConfig import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommandHello import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.EnDecrypt @@ -16,13 +18,13 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.Chara import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair.LTKExchanger import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.EapSqn import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.Session import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.SessionEstablisher import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.SessionKeys import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager import info.nightscout.androidaps.utils.extensions.toHex import io.reactivex.Observable import java.util.concurrent.BlockingQueue @@ -34,7 +36,8 @@ import javax.inject.Singleton @Singleton class OmnipodDashBleManagerImpl @Inject constructor( private val context: Context, - private val aapsLogger: AAPSLogger + private val aapsLogger: AAPSLogger, + private val podState: OmnipodDashPodStateManager ) : OmnipodDashBleManager { private val bluetoothManager: BluetoothManager = @@ -42,6 +45,8 @@ class OmnipodDashBleManagerImpl @Inject constructor( private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter private var sessionKeys: SessionKeys? = null private var msgIO: MessageIO? = null + private var gatt: BluetoothGatt? = null + private var status: ConnectionStatus = ConnectionStatus.IDLE @Throws( FailedToConnectException::class, @@ -54,30 +59,29 @@ class OmnipodDashBleManagerImpl @Inject constructor( DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class ) - private fun connect(podAddress: String): BleIO { - // TODO: locking? - val podDevice = bluetoothAdapter.getRemoteDevice(podAddress) + private fun connect(podDevice: BluetoothDevice): BleIO { val incomingPackets: Map> = mapOf( CharacteristicType.CMD to LinkedBlockingDeque(), CharacteristicType.DATA to LinkedBlockingDeque() ) val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets) - aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to $podAddress") + aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to ${podDevice.address}") val autoConnect = false // TODO: check what to use here - val gatt = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE) + val gattConnection = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE) bleCommCallbacks.waitForConnection(CONNECT_TIMEOUT_MS) val connectionState = bluetoothManager.getConnectionState(podDevice, BluetoothProfile.GATT) aapsLogger.debug(LTag.PUMPBTCOMM, "GATT connection state: $connectionState") if (connectionState != BluetoothProfile.STATE_CONNECTED) { - throw FailedToConnectException(podAddress) + throw FailedToConnectException(podDevice.address) } - val discoverer = ServiceDiscoverer(aapsLogger, gatt, bleCommCallbacks) + val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks) val chars = discoverer.discoverServices() - val bleIO = BleIO(aapsLogger, chars, incomingPackets, gatt, bleCommCallbacks) + val bleIO = BleIO(aapsLogger, chars, incomingPackets, gattConnection, bleCommCallbacks) bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandHello(CONTROLLER_ID).data) bleIO.readyToRead() + gatt = gattConnection return bleIO } @@ -117,7 +121,11 @@ class OmnipodDashBleManagerImpl @Inject constructor( } override fun getStatus(): ConnectionStatus { - TODO("not implemented") + var s: ConnectionStatus + synchronized(status) { + s = status + } + return s } @Throws( @@ -132,50 +140,77 @@ class OmnipodDashBleManagerImpl @Inject constructor( DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class ) + override fun connect(): Observable = Observable.create { emitter -> // TODO: when we are already connected, // emit PodEvent.AlreadyConnected, complete the observable and return from this method - try { - aapsLogger.info(LTag.PUMPBTCOMM, "starting new pod activation") + if (podState.bluetoothAddress == null) { + aapsLogger.info(LTag.PUMPBTCOMM, "starting new pod activation") - val podScanner = PodScanner(aapsLogger, bluetoothAdapter) - emitter.onNext(PodEvent.Scanning) + val podScanner = PodScanner(aapsLogger, bluetoothAdapter) + emitter.onNext(PodEvent.Scanning) - val podAddress = podScanner.scanForPod( - PodScanner.SCAN_FOR_SERVICE_UUID, - PodScanner.POD_ID_NOT_ACTIVATED - ).scanResult.device.address - // For tests: this.podAddress = "B8:27:EB:1D:7E:BB"; + val podAddress = podScanner.scanForPod( + PodScanner.SCAN_FOR_SERVICE_UUID, + PodScanner.POD_ID_NOT_ACTIVATED + ).scanResult.device.address + // For tests: this.podAddress = "B8:27:EB:1D:7E:BB"; + podState.bluetoothAddress = podAddress + } emitter.onNext(PodEvent.BluetoothConnecting) + val podAddress = podState.bluetoothAddress ?: throw FailedToConnectException("Lost connection") + // check if already connected + val podDevice = bluetoothAdapter.getRemoteDevice(podAddress) + val connectionState = bluetoothManager.getConnectionState(podDevice, BluetoothProfile.GATT) + aapsLogger.debug(LTag.PUMPBTCOMM, "GATT connection state: $connectionState") - val bleIO = connect(podAddress) emitter.onNext(PodEvent.BluetoothConnected(podAddress)) + if (connectionState == BluetoothProfile.STATE_CONNECTED) { + podState.uniqueId ?: throw FailedToConnectException("Already connection and uniqueId is missing") + emitter.onNext(PodEvent.AlreadyConnected(podAddress, podState.uniqueId ?: 0)) + emitter.onComplete() + return@create + } + if (msgIO != null) { + disconnect() + } + val bleIO = connect(podDevice) val mIO = MessageIO(aapsLogger, bleIO) val myId = Id.fromInt(CONTROLLER_ID) val podId = myId.increment() + var msgSeq = 1.toByte() + val ltkExchanger = LTKExchanger(aapsLogger, mIO, myId, podId, Id.fromLong(PodScanner.POD_ID_NOT_ACTIVATED)) + if (podState.ltk == null) { + emitter.onNext(PodEvent.Pairing) + val pairResult = ltkExchanger.negotiateLTK() + podState.ltk = pairResult.ltk + podState.uniqueId = podId.toLong() + msgSeq = pairResult.msgSeq + podState.eapAkaSequenceNumber = 1 + if (BuildConfig.DEBUG) { + aapsLogger.info(LTag.PUMPCOMM, "Got LTK: ${pairResult.ltk.toHex()}") + } + } - val ltkExchanger = LTKExchanger(aapsLogger, mIO) - - emitter.onNext(PodEvent.Pairing) - - val ltk = ltkExchanger.negotiateLTK() + val ltk: ByteArray = podState.ltk!! emitter.onNext(PodEvent.EstablishingSession) - - val eapSqn = EapSqn(1) - aapsLogger.info(LTag.PUMPCOMM, "Got LTK: ${ltk.ltk.toHex()}") - val eapAkaExchanger = SessionEstablisher(aapsLogger, mIO, ltk, eapSqn) + val eapSqn = podState.increaseEapAkaSequenceNumber() + val eapAkaExchanger = SessionEstablisher(aapsLogger, mIO, ltk, eapSqn, myId, podId, msgSeq) val keys = eapAkaExchanger.negotiateSessionKeys() - aapsLogger.info(LTag.PUMPCOMM, "CK: ${keys.ck.toHex()}") - aapsLogger.info(LTag.PUMPCOMM, "msgSequenceNumber: ${keys.msgSequenceNumber}") - aapsLogger.info(LTag.PUMPCOMM, "Nonce: ${keys.nonce}") + podState.commitEapAkaSequenceNumber() + if (BuildConfig.DEBUG) { + aapsLogger.info(LTag.PUMPCOMM, "CK: ${keys.ck.toHex()}") + aapsLogger.info(LTag.PUMPCOMM, "msgSequenceNumber: ${keys.msgSequenceNumber}") + aapsLogger.info(LTag.PUMPCOMM, "Nonce: ${keys.nonce}") + } sessionKeys = keys msgIO = mIO - emitter.onNext(PodEvent.Connected(ltk.podId.toLong())) + emitter.onNext(PodEvent.Connected(podId.toLong())) emitter.onComplete() } catch (ex: Exception) { @@ -184,7 +219,11 @@ class OmnipodDashBleManagerImpl @Inject constructor( } override fun disconnect() { - TODO("not implemented") + val localGatt = gatt + localGatt?.close() + gatt = null + msgIO = null + sessionKeys = null } companion object { diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt index 54a45fc54d..70d787b01e 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt @@ -11,9 +11,10 @@ class BleCommandAbort : BleCommand(BleCommandType.ABORT) class BleCommandSuccess : BleCommand(BleCommandType.SUCCESS) class BleCommandFail : BleCommand(BleCommandType.FAIL) + open class BleCommand(val data: ByteArray) { - constructor(type: BleCommandType) : this(byteArrayOf(type.value)) + constructor(type: BleCommandType) : this(byteArrayOf(type.value, 0)) constructor(type: BleCommandType, payload: ByteArray) : this( byteArrayOf(type.value) + payload diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoiner.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoiner.kt index 2cc75907c1..e4fe95c42e 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoiner.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoiner.kt @@ -32,7 +32,7 @@ class PayloadJoiner(private val firstPacket: ByteArray) { fullFragments == 0 -> { crc = ByteBuffer.wrap(firstPacket.copyOfRange(2, 6)).int.toUnsignedLong() val rest = firstPacket[6] - val end = min(rest + FirstBlePacket.HEADER_SIZE_WITHOUT_MIDDLE_PACKETS, BlePacket.MAX_SIZE) + val end = min(rest + FirstBlePacket.HEADER_SIZE_WITHOUT_MIDDLE_PACKETS, firstPacket.size) oneExtraPacket = rest + FirstBlePacket.HEADER_SIZE_WITHOUT_MIDDLE_PACKETS > end if (end > firstPacket.size) { throw IncorrectPacketException(0, firstPacket) @@ -78,12 +78,12 @@ class PayloadJoiner(private val firstPacket: ByteArray) { } crc = ByteBuffer.wrap(packet.copyOfRange(2, 6)).int.toUnsignedLong() val rest = packet[1].toInt() - val end = min(rest + LastBlePacket.HEADER_SIZE, BlePacket.MAX_SIZE) + val end = min(rest + LastBlePacket.HEADER_SIZE, packet.size) oneExtraPacket = rest + LastBlePacket.HEADER_SIZE > end if (packet.size < end) { throw IncorrectPacketException(idx.toByte(), packet) } - fragments.add(packet.copyOfRange(LastBlePacket.HEADER_SIZE, packet.size)) + fragments.add(packet.copyOfRange(LastBlePacket.HEADER_SIZE, end)) } idx > fullFragments -> { // this is the extra fragment diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt index f3a9615593..5965d11745 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt @@ -18,7 +18,7 @@ import org.spongycastle.crypto.macs.CMac import org.spongycastle.crypto.params.KeyParameter import java.security.SecureRandom -internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgIO: MessageIO) { +internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgIO: MessageIO, val myId: Id, val podId: Id, val podAddress: Id) { private val pdmPrivate = X25519.generatePrivateKey() private val pdmPublic = X25519.publicFromPrivate(pdmPrivate) @@ -27,8 +27,6 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI private val pdmNonce = ByteArray(NONCE_SIZE) private val pdmConf = ByteArray(CMAC_SIZE) private val podConf = ByteArray(CMAC_SIZE) - private val controllerId = Id.fromInt(OmnipodDashBleManagerImpl.CONTROLLER_ID) - val nodeId = controllerId.increment() private var seq: Byte = 1 private var ltk = ByteArray(CMAC_SIZE) @@ -39,7 +37,7 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI fun negotiateLTK(): PairResult { // send SP1, SP2 - val sp1sp2 = sp1sp2(nodeId.address, sp2()) + val sp1sp2 = sp1sp2(podId.address, sp2()) msgIO.sendMessage(sp1sp2.messagePacket) seq++ @@ -76,7 +74,6 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI return PairResult( ltk = ltk, - podId = nodeId, msgSeq = seq ) } @@ -88,8 +85,8 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI ) return PairMessage( sequenceNumber = seq, - source = controllerId, - destination = nodeId, + source = myId, + destination = podAddress, payload = payload ) } @@ -101,8 +98,8 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI ) return PairMessage( sequenceNumber = seq, - source = controllerId, - destination = nodeId, + source = myId, + destination = podAddress, payload = payload ) } @@ -125,8 +122,8 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI ) return PairMessage( sequenceNumber = seq, - source = controllerId, - destination = nodeId, + source = myId, + destination = podAddress, payload = payload ) } @@ -159,8 +156,8 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgI val payload = SP0GP0.toByteArray() return PairMessage( sequenceNumber = seq, - source = controllerId, - destination = nodeId, + source = myId, + destination = podAddress, payload = payload ) } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairResult.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairResult.kt index c6d087f38d..c23be1d0a5 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairResult.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/PairResult.kt @@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id import info.nightscout.androidaps.utils.extensions.toHex -data class PairResult(val ltk: ByteArray, val podId: Id, val msgSeq: Byte) { +data class PairResult(val ltk: ByteArray, val msgSeq: Byte) { init { require(ltk.size == 16) { "LTK length must be 16 bytes. Received LTK: ${ltk.toHex()}" } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessage.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessage.kt index 7f62c3b194..d25802c079 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessage.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessage.kt @@ -78,7 +78,7 @@ data class EapMessage( throw MessageIOException("Invalid eap payload. Expected AKA packet type: ${payload.toHex()}") } val attributesPayload = payload.copyOfRange(8, totalSize) - aapsLogger.debug(LTag.PUMPBTCOMM, "EAP attributes: ${attributesPayload.toByteString()}") + aapsLogger.debug(LTag.PUMPBTCOMM, "parsing EAP payload: ${payload.toHex()}") return EapMessage( code = EapCode.byValue(payload[0]), identifier = payload[1], diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt index 8a6c2a30c4..e8b89cc73c 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt @@ -3,32 +3,33 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManagerImpl import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.Nonce import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.SessionEstablishmentException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair.PairResult import info.nightscout.androidaps.utils.extensions.toHex import java.security.SecureRandom class SessionEstablisher( private val aapsLogger: AAPSLogger, private val msgIO: MessageIO, - private val ltk: PairResult, - private val eapSqn: EapSqn + private val ltk: ByteArray, + private val eapSqn: ByteArray, + private val myId: Id, + private val podId: Id, + private var msgSeq: Byte ) { - var sequenceNumber = ltk.msgSeq - private val controllerIV = ByteArray(IV_SIZE) private var nodeIV = ByteArray(IV_SIZE) - private val controllerId = Id.fromInt(OmnipodDashBleManagerImpl.CONTROLLER_ID) - private val milenage = Milenage(aapsLogger, ltk.ltk, eapSqn.increment()) + private val milenage = Milenage(aapsLogger, ltk, eapSqn) init { + require(eapSqn.size == 6) {"EAP-SQN has to be 6 bytes long"} + require(ltk.size == 16) {"LTK has to be 16 bytes long"} + aapsLogger.debug(LTag.PUMPBTCOMM, "Starting EAP-AKA") val random = SecureRandom() random.nextBytes(controllerIV) @@ -36,14 +37,14 @@ class SessionEstablisher( fun negotiateSessionKeys(): SessionKeys { // send EAP-AKA challenge - sequenceNumber++ // TODO: get from pod state. This only works for activating a new pod + msgSeq++ // TODO: get from pod state. This only works for activating a new pod var challenge = eapAkaChallenge() msgIO.sendMessage(challenge) val challengeResponse = msgIO.receiveMessage() processChallengeResponse(challengeResponse) // TODO: what do we have to answer if challenge response does not validate? - sequenceNumber++ + msgSeq++ var success = eapSuccess() msgIO.sendMessage(success) @@ -53,7 +54,7 @@ class SessionEstablisher( prefix = controllerIV + nodeIV, sqn = 0 ), - msgSequenceNumber = sequenceNumber + msgSequenceNumber = msgSeq ) } @@ -66,14 +67,14 @@ class SessionEstablisher( val eapMsg = EapMessage( code = EapCode.REQUEST, - identifier = 42, // TODO: find what value we need here, it's probably random + identifier = 189.toByte(), // TODO: find what value we need here, it's probably random attributes = attributes ) return MessagePacket( type = MessageType.SESSION_ESTABLISHMENT, - sequenceNumber = sequenceNumber, - source = controllerId, - destination = ltk.podId, + sequenceNumber = msgSeq, + source = myId, + destination = podId, payload = eapMsg.toByteArray() ) } @@ -103,14 +104,14 @@ class SessionEstablisher( val eapMsg = EapMessage( code = EapCode.SUCCESS, attributes = arrayOf(), - identifier = 44 // TODO: find what value we need here + identifier = 189.toByte() // TODO: find what value we need here ) return MessagePacket( type = MessageType.SESSION_ESTABLISHMENT, - sequenceNumber = sequenceNumber, - source = controllerId, - destination = ltk.podId, + sequenceNumber = msgSeq, + source = myId, + destination = podId, payload = eapMsg.toByteArray() ) } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/status/ConnectionStatus.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/status/ConnectionStatus.kt index 8343887516..6977f342f3 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/status/ConnectionStatus.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/status/ConnectionStatus.kt @@ -1,6 +1,10 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status enum class ConnectionStatus { - CONNECTED, - NOT_CONNECTED; + IDLE, + BUSY, + CONNECTING, + ESTABLISHING_SESSION, + PAIRING, + RUNNING_COMMAND; } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt index 8270e1cd18..49d3aceb79 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt @@ -23,6 +23,8 @@ interface OmnipodDashPodStateManager { val activationTime: Long? var uniqueId: Long? // TODO make Int var bluetoothAddress: String? + var ltk: ByteArray? + var eapAkaSequenceNumber: Long val bluetoothVersion: SoftwareVersion? val firmwareVersion: SoftwareVersion? @@ -46,6 +48,8 @@ interface OmnipodDashPodStateManager { val basalProgram: BasalProgram? fun increaseMessageSequenceNumber() + fun increaseEapAkaSequenceNumber():ByteArray + fun commitEapAkaSequenceNumber() fun updateFromDefaultStatusResponse(response: DefaultStatusResponse) fun updateFromVersionResponse(response: VersionResponse) fun updateFromSetUniqueIdResponse(response: SetUniqueIdResponse) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt index becac57345..c535536726 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt @@ -13,6 +13,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response. import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.VersionResponse import info.nightscout.androidaps.utils.sharedPreferences.SP import java.io.Serializable +import java.nio.ByteBuffer import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -150,6 +151,32 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( store() } + override var eapAkaSequenceNumber: Long + get() = podState.eapAkaSequenceNumber + set(value) { + podState.eapAkaSequenceNumber = value + store() + } + + override var ltk: ByteArray? + get() = podState.ltk + set(value) { + podState.ltk = value + store() + } + + override fun increaseEapAkaSequenceNumber():ByteArray { + podState.eapAkaSequenceNumber++ + return ByteBuffer.allocate(8) + .putLong(podState.eapAkaSequenceNumber) + .array() + .copyOfRange(2, 8) + } + + override fun commitEapAkaSequenceNumber() { + store() + } + override fun updateFromDefaultStatusResponse(response: DefaultStatusResponse) { podState.deliveryStatus = response.deliveryStatus podState.podStatus = response.podStatus @@ -262,6 +289,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( var activationTime: Long? = null var uniqueId: Long? = null var bluetoothAddress: String? = null + var ltk: ByteArray? = null + var eapAkaSequenceNumber: Long = 1 var bleVersion: SoftwareVersion? = null var firmwareVersion: SoftwareVersion? = null