From 647793e0b7ef12ac81f23f7455d64b20e3fcae4a Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Wed, 24 Feb 2021 18:07:19 +0100 Subject: [PATCH] Switch to Kotlin. and small fixes after conversion --- .../omnipod/dash/driver/comm/BleManager.java | 125 --------------- .../omnipod/dash/driver/comm/BleManager.kt | 99 ++++++++++++ .../dash/driver/comm/CharacteristicType.java | 35 ----- .../dash/driver/comm/CharacteristicType.kt | 26 ++++ ...ava => OmnipodDashCommunicationManager.kt} | 5 +- .../dash/driver/comm/ServiceDiscoverer.java | 75 --------- .../dash/driver/comm/ServiceDiscoverer.kt | 47 ++++++ .../comm/callbacks/BleCommCallbacks.java | 147 ------------------ .../driver/comm/callbacks/BleCommCallbacks.kt | 142 +++++++++++++++++ .../CharacteristicWriteConfirmation.java | 11 -- .../CharacteristicWriteConfirmation.kt | 3 + .../DescriptorWriteConfirmation.java | 11 -- .../callbacks/DescriptorWriteConfirmation.kt | 3 + .../dash/driver/comm/command/BleCommand.java | 22 --- .../dash/driver/comm/command/BleCommand.kt | 21 +++ .../driver/comm/command/BleCommandHello.java | 14 -- .../driver/comm/command/BleCommandHello.kt | 10 ++ .../driver/comm/command/BleCommandType.java | 30 ---- .../driver/comm/command/BleCommandType.kt | 17 ++ .../comm/exceptions/BleIOBusyException.java | 4 - .../comm/exceptions/BleIOBusyException.kt | 3 + .../CharacteristicNotFoundException.java | 7 - .../CharacteristicNotFoundException.kt | 3 + ...uldNotConfirmDescriptorWriteException.java | 12 -- ...CouldNotConfirmDescriptorWriteException.kt | 3 + .../comm/exceptions/CouldNotConfirmWrite.java | 13 -- .../comm/exceptions/CouldNotConfirmWrite.kt | 10 ++ .../CouldNotEnableNotifications.java | 9 -- .../exceptions/CouldNotEnableNotifications.kt | 5 + .../exceptions/CouldNotSendBleException.java | 7 - .../exceptions/CouldNotSendBleException.kt | 3 + .../DescriptorNotFoundException.java | 4 - .../exceptions/DescriptorNotFoundException.kt | 3 + .../DiscoveredInvalidPodException.java | 11 -- .../DiscoveredInvalidPodException.kt | 5 + .../exceptions/FailedToConnectException.java | 11 -- .../exceptions/FailedToConnectException.kt | 6 + .../comm/exceptions/ScanFailException.java | 10 -- .../comm/exceptions/ScanFailException.kt | 6 + .../ScanFailFoundTooManyException.java | 20 --- .../ScanFailFoundTooManyException.kt | 15 ++ .../exceptions/ScanFailNotFoundException.java | 4 - .../exceptions/ScanFailNotFoundException.kt | 3 + .../exceptions/ServiceNotFoundException.java | 7 - .../exceptions/ServiceNotFoundException.kt | 3 + .../omnipod/dash/driver/comm/io/BleIO.java | 140 ----------------- .../pump/omnipod/dash/driver/comm/io/BleIO.kt | 104 +++++++++++++ .../omnipod/dash/driver/comm/io/IOState.java | 7 - .../omnipod/dash/driver/comm/io/IOState.kt | 5 + .../packet/{BlePacket.java => BlePacket.kt} | 5 +- .../driver/comm/scan/BleDiscoveredDevice.java | 94 ----------- .../driver/comm/scan/BleDiscoveredDevice.kt | 78 ++++++++++ .../dash/driver/comm/scan/PodScanner.java | 62 -------- .../dash/driver/comm/scan/PodScanner.kt | 48 ++++++ .../dash/driver/comm/scan/ScanCollector.java | 66 -------- .../dash/driver/comm/scan/ScanCollector.kt | 51 ++++++ 56 files changed, 726 insertions(+), 964 deletions(-) delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/BleManager.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/BleManager.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/CharacteristicType.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/CharacteristicType.kt rename omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/{OmnipodDashCommunicationManager.java => OmnipodDashCommunicationManager.kt} (50%) delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/CharacteristicWriteConfirmation.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/CharacteristicWriteConfirmation.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/DescriptorWriteConfirmation.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/DescriptorWriteConfirmation.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandHello.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandHello.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BleIOBusyException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BleIOBusyException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CharacteristicNotFoundException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CharacteristicNotFoundException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmDescriptorWriteException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmDescriptorWriteException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmWrite.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmWrite.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotEnableNotifications.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotEnableNotifications.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendBleException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendBleException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DescriptorNotFoundException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DescriptorNotFoundException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DiscoveredInvalidPodException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DiscoveredInvalidPodException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailNotFoundException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailNotFoundException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ServiceNotFoundException.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ServiceNotFoundException.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.kt rename omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/{BlePacket.java => BlePacket.kt} (59%) delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.kt delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.java create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/BleManager.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/BleManager.java deleted file mode 100644 index 35164c4cc1..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/BleManager.java +++ /dev/null @@ -1,125 +0,0 @@ -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.BluetoothGattCharacteristic; -import android.bluetooth.BluetoothManager; -import android.bluetooth.BluetoothProfile; -import android.content.Context; - -import java.util.Collections; -import java.util.EnumMap; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.TimeoutException; - -import javax.inject.Inject; -import javax.inject.Singleton; - -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.exceptions.BleIOBusyException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmDescriptorWriteException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmWrite; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotEnableNotifications; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.DescriptorNotFoundException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.BleIO; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotSendBleException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.FailedToConnectException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner; - -@Singleton -public class BleManager implements OmnipodDashCommunicationManager { - private static final int CONNECT_TIMEOUT_MS = 5000; - private static final int CONTROLLER_ID = 4242; // TODO read from preferences or somewhere else. - - private static BleManager instance = null; - private final Context context; - private final BluetoothAdapter bluetoothAdapter; - private final BluetoothManager bluetoothManager; - @Inject AAPSLogger aapsLogger; - private String podAddress; - private BluetoothGatt gatt; - private BleIO bleio; - - @Inject - public BleManager(Context context) { - this.context = context; - this.bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); - this.bluetoothAdapter = bluetoothManager.getAdapter(); - } - - public static BleManager getInstance(Context context) { - BleManager ret; - synchronized (BleManager.class) { - if (instance == null) { - instance = new BleManager(context); - } - ret = instance; - } - return ret; - } - - public void activateNewPod() - throws InterruptedException, - ScanFailException, - FailedToConnectException, - CouldNotSendBleException, - BleIOBusyException, - TimeoutException, - CouldNotConfirmWrite, CouldNotEnableNotifications, DescriptorNotFoundException, CouldNotConfirmDescriptorWriteException { - this.aapsLogger.info(LTag.PUMPBTCOMM, "starting new pod activation"); - PodScanner podScanner = new PodScanner(this.aapsLogger, this.bluetoothAdapter); - this.podAddress = podScanner.scanForPod(PodScanner.SCAN_FOR_SERVICE_UUID, PodScanner.POD_ID_NOT_ACTIVATED).getScanResult().getDevice().getAddress(); - // For tests: this.podAddress = "B8:27:EB:1D:7E:BB"; - this.connect(); - } - - public void connect() - throws FailedToConnectException, - CouldNotSendBleException, - InterruptedException, - BleIOBusyException, TimeoutException, CouldNotConfirmWrite, CouldNotEnableNotifications, DescriptorNotFoundException, CouldNotConfirmDescriptorWriteException { - // TODO: locking? - - BluetoothDevice podDevice = this.bluetoothAdapter.getRemoteDevice(this.podAddress); - - Map> incomingPackets = new EnumMap>(CharacteristicType.class); - incomingPackets.put(CharacteristicType.CMD, new LinkedBlockingDeque<>()); - incomingPackets.put(CharacteristicType.DATA, new LinkedBlockingDeque<>()); - incomingPackets = Collections.unmodifiableMap(incomingPackets); - - BleCommCallbacks bleCommCallbacks = new BleCommCallbacks(aapsLogger, incomingPackets); - - aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to " + this.podAddress); - boolean autoConnect = true; - if (BuildConfig.DEBUG) { - autoConnect = false; - // TODO: remove this in the future - // it's easier to start testing from scratch on each run. - } - gatt = podDevice.connectGatt(this.context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE); - - bleCommCallbacks.waitForConnection(CONNECT_TIMEOUT_MS); - - int connectionState = this.bluetoothManager.getConnectionState(podDevice, BluetoothProfile.GATT); - aapsLogger.debug(LTag.PUMPBTCOMM, "GATT connection state: " + connectionState); - if (connectionState != BluetoothProfile.STATE_CONNECTED) { - throw new FailedToConnectException(this.podAddress); - } - - ServiceDiscoverer discoverer = new ServiceDiscoverer(this.aapsLogger, gatt, bleCommCallbacks); - Map chars = discoverer.discoverServices(); - - this.bleio = new BleIO(aapsLogger, chars, incomingPackets, gatt, bleCommCallbacks); - this.aapsLogger.debug(LTag.PUMPBTCOMM, "Saying hello to the pod"); - this.bleio.sendAndConfirmPacket(CharacteristicType.CMD, new BleCommandHello(CONTROLLER_ID).asByteArray()); - this.bleio.readyToRead(); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/BleManager.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/BleManager.kt new file mode 100644 index 0000000000..630d57c1b9 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/BleManager.kt @@ -0,0 +1,99 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm + + +import javax.inject.Singleton +import javax.inject.Inject +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashCommunicationManager +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothManager +import info.nightscout.androidaps.logging.AAPSLogger +import android.bluetooth.BluetoothGatt +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.BleIO +import kotlin.Throws +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.FailedToConnectException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotSendBleException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.BleIOBusyException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmWrite +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotEnableNotifications +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.DescriptorNotFoundException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmDescriptorWriteException +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner +import android.bluetooth.BluetoothDevice +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.BleManager +import android.bluetooth.BluetoothProfile +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ServiceDiscoverer +import android.bluetooth.BluetoothGattCharacteristic +import android.content.Context +import info.nightscout.androidaps.plugins.pump.omnipod.dash.BuildConfig +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommandHello +import java.util.* +import java.util.concurrent.BlockingQueue +import java.util.concurrent.LinkedBlockingDeque +import java.util.concurrent.TimeoutException + +@Singleton +class BleManager @Inject constructor(private val context: Context) : OmnipodDashCommunicationManager { + + private val bluetoothAdapter: BluetoothAdapter + private val bluetoothManager: BluetoothManager + + @Inject lateinit var aapsLogger: AAPSLogger + private var podAddress: String? = null + private var gatt: BluetoothGatt? = null + private var bleio: BleIO? = null + @Throws(InterruptedException::class, ScanFailException::class, FailedToConnectException::class, CouldNotSendBleException::class, BleIOBusyException::class, TimeoutException::class, CouldNotConfirmWrite::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class) + fun activateNewPod() { + aapsLogger.info(LTag.PUMPBTCOMM, "starting new pod activation") + val podScanner = PodScanner(aapsLogger, bluetoothAdapter) + 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"; + connect() + } + + @Throws(FailedToConnectException::class, CouldNotSendBleException::class, InterruptedException::class, BleIOBusyException::class, TimeoutException::class, CouldNotConfirmWrite::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class) + fun connect() { + // TODO: locking? + val podDevice = bluetoothAdapter.getRemoteDevice(podAddress) + var incomingPackets: Map> = + mapOf(CharacteristicType.CMD to LinkedBlockingDeque(), + CharacteristicType.DATA to LinkedBlockingDeque()); + val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets) + aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to " + podAddress) + var autoConnect = true + if (BuildConfig.DEBUG) { + autoConnect = false + // TODO: remove this in the future + // it's easier to start testing from scratch on each run. + } + val gatt = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE) + this.gatt = gatt + + 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) + } + val discoverer = ServiceDiscoverer(aapsLogger, gatt, bleCommCallbacks) + val chars = discoverer.discoverServices() + bleio = BleIO(aapsLogger, chars, incomingPackets, gatt, bleCommCallbacks) + aapsLogger.debug(LTag.PUMPBTCOMM, "Saying hello to the pod") + bleio!!.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandHello(CONTROLLER_ID).asByteArray()) + bleio!!.readyToRead() + } + + companion object { + + private const val CONNECT_TIMEOUT_MS = 5000 + private const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else. + } + + init { + bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager + bluetoothAdapter = bluetoothManager.adapter + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/CharacteristicType.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/CharacteristicType.java deleted file mode 100644 index 73bcc9de61..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/CharacteristicType.java +++ /dev/null @@ -1,35 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm; - -import java.math.BigInteger; -import java.util.UUID; - -public enum CharacteristicType { - CMD("1a7e2441-e3ed-4464-8b7e-751e03d0dc5f"), - DATA("1a7e2442-e3ed-4464-8b7e-751e03d0dc5f"); - - public final String value; - - CharacteristicType(String value) { - this.value = value; - } - - public static CharacteristicType byValue(String value) { - for (CharacteristicType type : values()) { - if (type.value.equals(value)) { - return type; - } - } - throw new IllegalArgumentException("Unknown Characteristic Type: " + value); - } - - public String getValue() { - return this.value; - } - - public UUID getUUID() { - return new UUID( - new BigInteger(this.value.replace("-", "").substring(0, 16), 16).longValue(), - new BigInteger(this.value.replace("-", "").substring(16), 16).longValue() - ); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/CharacteristicType.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/CharacteristicType.kt new file mode 100644 index 0000000000..600e4ba769 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/CharacteristicType.kt @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm + +import java.math.BigInteger +import java.util.* + +enum class CharacteristicType(val value: String) { + CMD("1a7e2441-e3ed-4464-8b7e-751e03d0dc5f"), DATA("1a7e2442-e3ed-4464-8b7e-751e03d0dc5f"); + + val uUID: UUID + get() = UUID( + BigInteger(value.replace("-", "").substring(0, 16), 16).toLong(), + BigInteger(value.replace("-", "").substring(16), 16).toLong() + ) + + companion object { + + @JvmStatic fun byValue(value: String): CharacteristicType { + for (type in values()) { + if (type.value == value) { + return type + } + } + throw IllegalArgumentException("Unknown Characteristic Type: $value") + } + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashCommunicationManager.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashCommunicationManager.kt similarity index 50% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashCommunicationManager.java rename to omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashCommunicationManager.kt index a53f3e2b34..db95a2046b 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashCommunicationManager.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashCommunicationManager.kt @@ -1,4 +1,3 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm; +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm -public interface OmnipodDashCommunicationManager { -} +interface OmnipodDashCommunicationManager \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.java deleted file mode 100644 index 13828db4d0..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.java +++ /dev/null @@ -1,75 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm; - -import android.bluetooth.BluetoothGatt; -import android.bluetooth.BluetoothGattCharacteristic; -import android.bluetooth.BluetoothGattService; - -import java.math.BigInteger; -import java.util.Collections; -import java.util.EnumMap; -import java.util.Map; -import java.util.UUID; - -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CharacteristicNotFoundException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ServiceNotFoundException; - -public class ServiceDiscoverer { - private static final String SERVICE_UUID = "1a7e-4024-e3ed-4464-8b7e-751e03d0dc5f"; - private static final int DISCOVER_SERVICES_TIMEOUT_MS = 5000; - - private final BluetoothGatt gatt; - private final BleCommCallbacks bleCallbacks; - private final AAPSLogger logger; - private Map chars; - - public ServiceDiscoverer(AAPSLogger logger, BluetoothGatt gatt, BleCommCallbacks bleCallbacks) { - this.gatt = gatt; - this.bleCallbacks = bleCallbacks; - this.logger = logger; - } - - private static UUID uuidFromString(String s) { - return new UUID( - new BigInteger(s.replace("-", "").substring(0, 16), 16).longValue(), - new BigInteger(s.replace("-", "").substring(16), 16).longValue() - ); - } - - /*** - * This is first step after connection establishment - */ - public Map discoverServices() - throws InterruptedException, - ServiceNotFoundException, - CharacteristicNotFoundException { - - logger.debug(LTag.PUMPBTCOMM, "Discovering services"); - gatt.discoverServices(); - this.bleCallbacks.waitForServiceDiscovery(DISCOVER_SERVICES_TIMEOUT_MS); - logger.debug(LTag.PUMPBTCOMM, "Services discovered"); - - BluetoothGattService service = gatt.getService( - uuidFromString(SERVICE_UUID)); - if (service == null) { - throw new ServiceNotFoundException(SERVICE_UUID); - } - BluetoothGattCharacteristic cmdChar = service.getCharacteristic(CharacteristicType.CMD.getUUID()); - if (cmdChar == null) { - throw new CharacteristicNotFoundException(CharacteristicType.CMD.getValue()); - } - BluetoothGattCharacteristic dataChar = service.getCharacteristic(CharacteristicType.DATA.getUUID()); - if (dataChar == null) { - throw new CharacteristicNotFoundException(CharacteristicType.DATA.getValue()); - } - Map chars = new EnumMap(CharacteristicType.class); - chars.put(CharacteristicType.CMD, cmdChar); - chars.put(CharacteristicType.DATA, dataChar); - this.chars = Collections.unmodifiableMap(chars); - return this.chars; - } - -} - diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt new file mode 100644 index 0000000000..85694a213a --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt @@ -0,0 +1,47 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm + +import android.bluetooth.BluetoothGatt +import android.bluetooth.BluetoothGattCharacteristic +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CharacteristicNotFoundException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ServiceNotFoundException +import java.math.BigInteger +import java.util.* + +class ServiceDiscoverer(private val logger: AAPSLogger, private val gatt: BluetoothGatt, private val bleCallbacks: BleCommCallbacks) { + + /*** + * This is first step after connection establishment + */ + @Throws(InterruptedException::class, ServiceNotFoundException::class, CharacteristicNotFoundException::class) + fun discoverServices(): Map { + logger.debug(LTag.PUMPBTCOMM, "Discovering services") + gatt.discoverServices() + bleCallbacks.waitForServiceDiscovery(DISCOVER_SERVICES_TIMEOUT_MS) + logger.debug(LTag.PUMPBTCOMM, "Services discovered") + val service = gatt.getService( + uuidFromString(SERVICE_UUID)) + ?: throw ServiceNotFoundException(SERVICE_UUID) + val cmdChar = service.getCharacteristic(CharacteristicType.CMD.uUID) + ?: throw CharacteristicNotFoundException(CharacteristicType.CMD.value) + val dataChar = service.getCharacteristic(CharacteristicType.DATA.uUID) + ?: throw CharacteristicNotFoundException(CharacteristicType.DATA.value) + var chars = mapOf(CharacteristicType.CMD to cmdChar, + CharacteristicType.DATA to dataChar) + return chars + } + + companion object { + private const val SERVICE_UUID = "1a7e-4024-e3ed-4464-8b7e-751e03d0dc5f" + private const val DISCOVER_SERVICES_TIMEOUT_MS = 5000 + private fun uuidFromString(s: String): UUID { + return UUID( + BigInteger(s.replace("-", "").substring(0, 16), 16).toLong(), + BigInteger(s.replace("-", "").substring(16), 16).toLong() + ) + } + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.java deleted file mode 100644 index 28a202606e..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.java +++ /dev/null @@ -1,147 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks; - -import android.bluetooth.BluetoothGatt; -import android.bluetooth.BluetoothGattCallback; -import android.bluetooth.BluetoothGattCharacteristic; -import android.bluetooth.BluetoothGattDescriptor; -import android.bluetooth.BluetoothProfile; - -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmDescriptorWriteException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmWrite; - -public class BleCommCallbacks extends BluetoothGattCallback { - private final static int WRITE_CONFIRM_TIMEOUT_MS = 10; // the other thread should be waiting for the exchange - - private final CountDownLatch serviceDiscoveryComplete; - private final CountDownLatch connected; - private final AAPSLogger aapsLogger; - private final Map> incomingPackets; - private final BlockingQueue writeQueue; - private final BlockingQueue descriptorWriteQueue; - - public BleCommCallbacks(AAPSLogger aapsLogger, Map> incomingPackets) { - this.serviceDiscoveryComplete = new CountDownLatch(1); - this.connected = new CountDownLatch(1); - this.aapsLogger = aapsLogger; - this.incomingPackets = incomingPackets; - this.writeQueue = new LinkedBlockingQueue<>(1); - this.descriptorWriteQueue = new LinkedBlockingQueue<>(1); - } - - @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { - super.onConnectionStateChange(gatt, status, newState); - this.aapsLogger.debug(LTag.PUMPBTCOMM, "OnConnectionStateChange discovered with status/state" + status + "/" + newState); - if (newState == BluetoothProfile.STATE_CONNECTED && status == BluetoothGatt.GATT_SUCCESS) { - this.connected.countDown(); - } - } - - @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { - super.onServicesDiscovered(gatt, status); - this.aapsLogger.debug(LTag.PUMPBTCOMM, "OnServicesDiscovered with status" + status); - if (status == BluetoothGatt.GATT_SUCCESS) { - this.serviceDiscoveryComplete.countDown(); - } - } - - public void waitForConnection(int timeout_ms) - throws InterruptedException { - this.connected.await(timeout_ms, TimeUnit.MILLISECONDS); - } - - public void waitForServiceDiscovery(int timeout_ms) - throws InterruptedException { - this.serviceDiscoveryComplete.await(timeout_ms, TimeUnit.MILLISECONDS); - } - - public void confirmWrite(CharacteristicType characteristicType, byte[] expectedPayload, int timeout_ms) throws InterruptedException, TimeoutException, CouldNotConfirmWrite { - CharacteristicWriteConfirmation received = this.writeQueue.poll(timeout_ms, TimeUnit.MILLISECONDS); - if (received == null ) { - throw new TimeoutException(); - } - if (!Arrays.equals(expectedPayload, received.payload)) { - this.aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm write. Got " + received.payload + ".Excepted: " + expectedPayload + ". Status: "+received.status); - throw new CouldNotConfirmWrite(expectedPayload, received.payload); - } - this.aapsLogger.debug(LTag.PUMPBTCOMM, "Confirmed write with value: " + received.payload); - } - - @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { - super.onCharacteristicWrite(gatt, characteristic, status); - byte[] received = null; - - if (status == BluetoothGatt.GATT_SUCCESS) { - received = characteristic.getValue(); - this.aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite value " + characteristic.getStringValue(0)); - } - - this.aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite with status/char/value " + - status + "/" + - CharacteristicType.byValue(characteristic.getUuid().toString()) + "/" + - received); - try { - if (this.writeQueue.size() > 0) { - this.aapsLogger.warn(LTag.PUMPBTCOMM, "Write confirm queue should be empty. found: "+ this.writeQueue.size()); - this.writeQueue.clear(); - } - boolean offered = this.writeQueue.offer(new CharacteristicWriteConfirmation(received, status), WRITE_CONFIRM_TIMEOUT_MS, TimeUnit.MILLISECONDS); - if (!offered) { - this.aapsLogger.warn(LTag.PUMPBTCOMM, "Received delayed write confirmation"); - } - } catch (InterruptedException e) { - this.aapsLogger.warn(LTag.PUMPBTCOMM, "Interrupted while sending write confirmation"); - } - } - - @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { - super.onCharacteristicChanged(gatt, characteristic); - - byte[] payload = characteristic.getValue(); - CharacteristicType characteristicType = CharacteristicType.byValue(characteristic.getUuid().toString()); - this.aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicChanged with char/value " + - characteristicType + "/" + - payload); - this.incomingPackets.get(characteristicType).add(payload); - } - - public void confirmWriteDescriptor(String descriptorUUID, int timeout_ms) throws InterruptedException, CouldNotConfirmDescriptorWriteException { - DescriptorWriteConfirmation confirmed = this.descriptorWriteQueue.poll(timeout_ms, TimeUnit.MILLISECONDS); - if (!descriptorUUID.equals(confirmed.uuid)) { - this.aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm descriptor write. Got " + confirmed.uuid + ".Expected: " + descriptorUUID + ". Status: " + confirmed.status); - throw new CouldNotConfirmDescriptorWriteException(confirmed.uuid, descriptorUUID); - } - } - - @Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { - super.onDescriptorWrite(gatt, descriptor, status); - String uuid = null; - if (status == BluetoothGatt.GATT_SUCCESS) { - uuid = descriptor.getUuid().toString(); - } - DescriptorWriteConfirmation confirmation = new DescriptorWriteConfirmation(status, uuid); - try { - if (this.descriptorWriteQueue.size() > 0) { - this.aapsLogger.warn(LTag.PUMPBTCOMM, "Descriptor write queue should be empty, found: "+ this.descriptorWriteQueue.size()); - this.descriptorWriteQueue.clear(); - } - - boolean offered = this.descriptorWriteQueue.offer(confirmation, WRITE_CONFIRM_TIMEOUT_MS, TimeUnit.MILLISECONDS); - if (!offered) { - this.aapsLogger.warn(LTag.PUMPBTCOMM, "Received delayed descriptor write confirmation"); - } - } catch (InterruptedException e) { - this.aapsLogger.warn(LTag.PUMPBTCOMM, "Interrupted while sending descriptor write confirmation"); - } - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt new file mode 100644 index 0000000000..1998d9b307 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt @@ -0,0 +1,142 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks + +import android.bluetooth.BluetoothGatt +import android.bluetooth.BluetoothGattCallback +import android.bluetooth.BluetoothGattCharacteristic +import android.bluetooth.BluetoothGattDescriptor +import android.bluetooth.BluetoothProfile +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType.Companion.byValue +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmDescriptorWriteException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmWrite +import java.util.* +import java.util.concurrent.BlockingQueue +import java.util.concurrent.CountDownLatch +import java.util.concurrent.LinkedBlockingQueue +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +class BleCommCallbacks(aapsLogger: AAPSLogger, incomingPackets: Map>) : BluetoothGattCallback() { + + private val serviceDiscoveryComplete: CountDownLatch + private val connected: CountDownLatch + private val aapsLogger: AAPSLogger + private val incomingPackets: Map> + private val writeQueue: BlockingQueue + private val descriptorWriteQueue: BlockingQueue + override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) { + super.onConnectionStateChange(gatt, status, newState) + aapsLogger.debug(LTag.PUMPBTCOMM, "OnConnectionStateChange discovered with status/state$status/$newState") + if (newState == BluetoothProfile.STATE_CONNECTED && status == BluetoothGatt.GATT_SUCCESS) { + connected.countDown() + } + } + + override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { + super.onServicesDiscovered(gatt, status) + aapsLogger.debug(LTag.PUMPBTCOMM, "OnServicesDiscovered with status$status") + if (status == BluetoothGatt.GATT_SUCCESS) { + serviceDiscoveryComplete.countDown() + } + } + + @Throws(InterruptedException::class) fun waitForConnection(timeout_ms: Int) { + connected.await(timeout_ms.toLong(), TimeUnit.MILLISECONDS) + } + + @Throws(InterruptedException::class) fun waitForServiceDiscovery(timeout_ms: Int) { + serviceDiscoveryComplete.await(timeout_ms.toLong(), TimeUnit.MILLISECONDS) + } + + @Throws(InterruptedException::class, TimeoutException::class, CouldNotConfirmWrite::class) + fun confirmWrite(expectedPayload: ByteArray, timeout_ms: Int) { + val received = writeQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS) + ?: throw TimeoutException() + if (!Arrays.equals(expectedPayload, received.payload)) { + aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm write. Got " + received.payload + ".Excepted: " + expectedPayload + ". Status: " + received.status) + throw CouldNotConfirmWrite(expectedPayload, received.payload!!) + } + aapsLogger.debug(LTag.PUMPBTCOMM, "Confirmed write with value: " + received.payload) + } + + override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) { + super.onCharacteristicWrite(gatt, characteristic, status) + var received: ByteArray? = null + if (status == BluetoothGatt.GATT_SUCCESS) { + received = characteristic.value + aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite value " + characteristic.getStringValue(0)) + } + aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite with status/char/value " + + status + "/" + + byValue(characteristic.uuid.toString()) + "/" + + received) + try { + if (writeQueue.size > 0) { + aapsLogger.warn(LTag.PUMPBTCOMM, "Write confirm queue should be empty. found: " + writeQueue.size) + writeQueue.clear() + } + val offered = writeQueue.offer(CharacteristicWriteConfirmation(received, status), WRITE_CONFIRM_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS) + if (!offered) { + aapsLogger.warn(LTag.PUMPBTCOMM, "Received delayed write confirmation") + } + } catch (e: InterruptedException) { + aapsLogger.warn(LTag.PUMPBTCOMM, "Interrupted while sending write confirmation") + } + } + + override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) { + super.onCharacteristicChanged(gatt, characteristic) + val payload = characteristic.value + val characteristicType = byValue(characteristic.uuid.toString()) + aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicChanged with char/value " + + characteristicType + "/" + + payload) + incomingPackets[characteristicType]!!.add(payload) + } + + @Throws(InterruptedException::class, CouldNotConfirmDescriptorWriteException::class) + fun confirmWriteDescriptor(descriptorUUID: String, timeout_ms: Int) { + val confirmed = descriptorWriteQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS) + if (descriptorUUID != confirmed.uuid) { + aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm descriptor write. Got " + confirmed.uuid + ".Expected: " + descriptorUUID + ". Status: " + confirmed.status) + throw CouldNotConfirmDescriptorWriteException(confirmed.uuid!!, descriptorUUID) + } + } + + override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) { + super.onDescriptorWrite(gatt, descriptor, status) + var uuid: String? = null + if (status == BluetoothGatt.GATT_SUCCESS) { + uuid = descriptor.uuid.toString() + } + val confirmation = DescriptorWriteConfirmation(status, uuid) + try { + if (descriptorWriteQueue.size > 0) { + aapsLogger.warn(LTag.PUMPBTCOMM, "Descriptor write queue should be empty, found: " + descriptorWriteQueue.size) + descriptorWriteQueue.clear() + } + val offered = descriptorWriteQueue.offer(confirmation, WRITE_CONFIRM_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS) + if (!offered) { + aapsLogger.warn(LTag.PUMPBTCOMM, "Received delayed descriptor write confirmation") + } + } catch (e: InterruptedException) { + aapsLogger.warn(LTag.PUMPBTCOMM, "Interrupted while sending descriptor write confirmation") + } + } + + companion object { + + private const val WRITE_CONFIRM_TIMEOUT_MS = 10 // the other thread should be waiting for the exchange + } + + init { + serviceDiscoveryComplete = CountDownLatch(1) + connected = CountDownLatch(1) + this.aapsLogger = aapsLogger + this.incomingPackets = incomingPackets + writeQueue = LinkedBlockingQueue(1) + descriptorWriteQueue = LinkedBlockingQueue(1) + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/CharacteristicWriteConfirmation.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/CharacteristicWriteConfirmation.java deleted file mode 100644 index cf2e8bff77..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/CharacteristicWriteConfirmation.java +++ /dev/null @@ -1,11 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks; - -public class CharacteristicWriteConfirmation { - public byte[] payload; - public int status; - - public CharacteristicWriteConfirmation(byte[] payload, int status) { - this.payload = payload; - this.status = status; - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/CharacteristicWriteConfirmation.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/CharacteristicWriteConfirmation.kt new file mode 100644 index 0000000000..76a5db2f63 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/CharacteristicWriteConfirmation.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks + +class CharacteristicWriteConfirmation(var payload: ByteArray?, var status: Int) \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/DescriptorWriteConfirmation.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/DescriptorWriteConfirmation.java deleted file mode 100644 index 88ae897b1b..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/DescriptorWriteConfirmation.java +++ /dev/null @@ -1,11 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks; - -public class DescriptorWriteConfirmation { - public int status; - public String uuid; - - public DescriptorWriteConfirmation(int status, String uuid) { - this.status = status; - this.uuid = uuid; - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/DescriptorWriteConfirmation.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/DescriptorWriteConfirmation.kt new file mode 100644 index 0000000000..c975393d7c --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/DescriptorWriteConfirmation.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks + +class DescriptorWriteConfirmation(var status: Int, var uuid: String?) \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.java deleted file mode 100644 index 4af111d633..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.java +++ /dev/null @@ -1,22 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command; - -import org.jetbrains.annotations.NotNull; - -public abstract class BleCommand { - private final byte[] data; - - public BleCommand(@NotNull BleCommandType type) { - this.data = new byte[]{type.getValue()}; - } - - public BleCommand(@NotNull BleCommandType type, @NotNull byte[] payload) { - int n = payload.length + 1; - this.data = new byte[n]; - this.data[0] = type.getValue(); - System.arraycopy(payload, 0, data, 1, payload.length); - } - - public byte[] asByteArray() { - return this.data; - } -} 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 new file mode 100644 index 0000000000..d5483f3d37 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt @@ -0,0 +1,21 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command + +abstract class BleCommand { + + private val data: ByteArray + + constructor(type: BleCommandType) { + data = byteArrayOf(type.value) + } + + constructor(type: BleCommandType, payload: ByteArray) { + val n = payload.size + 1 + data = ByteArray(n) + data[0] = type.value + System.arraycopy(payload, 0, data, 1, payload.size) + } + + fun asByteArray(): ByteArray { + return data + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandHello.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandHello.java deleted file mode 100644 index 56659f45e5..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandHello.java +++ /dev/null @@ -1,14 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command; - -import java.nio.ByteBuffer; - -public class BleCommandHello extends BleCommand { - public BleCommandHello(int controllerId) { - super(BleCommandType.HELLO, - ByteBuffer.allocate(6) - .put((byte) 1) // TODO find the meaning of this constant - .put((byte) 4) // TODO find the meaning of this constant - .putInt(controllerId).array() - ); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandHello.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandHello.kt new file mode 100644 index 0000000000..03414989b2 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandHello.kt @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command + +import java.nio.ByteBuffer + +class BleCommandHello(controllerId: Int) : BleCommand(BleCommandType.HELLO, + ByteBuffer.allocate(6) + .put(1.toByte()) // TODO find the meaning of this constant + .put(4.toByte()) // TODO find the meaning of this constant + .putInt(controllerId).array() +) \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.java deleted file mode 100644 index 38225bf799..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.java +++ /dev/null @@ -1,30 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command; - -public enum BleCommandType { - RTS((byte) 0x00), - CTS((byte) 0x01), - NACK((byte) 0x02), - ABORT((byte) 0x03), - SUCCESS((byte) 0x04), - FAIL((byte) 0x05), - HELLO((byte) 0x06); - - public final byte value; - - BleCommandType(byte value) { - this.value = value; - } - - public static BleCommandType byValue(byte value) { - for (BleCommandType type : values()) { - if (type.value == value) { - return type; - } - } - throw new IllegalArgumentException("Unknown BleCommandType: " + value); - } - - public byte getValue() { - return this.value; - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt new file mode 100644 index 0000000000..7dd91d00e1 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt @@ -0,0 +1,17 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command + +enum class BleCommandType(val value: Byte) { + RTS(0x00.toByte()), CTS(0x01.toByte()), NACK(0x02.toByte()), ABORT(0x03.toByte()), SUCCESS(0x04.toByte()), FAIL(0x05.toByte()), HELLO(0x06.toByte()); + + companion object { + + fun byValue(value: Byte): BleCommandType { + for (type in values()) { + if (type.value == value) { + return type + } + } + throw IllegalArgumentException("Unknown BleCommandType: $value") + } + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BleIOBusyException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BleIOBusyException.java deleted file mode 100644 index 53f85c5a6f..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BleIOBusyException.java +++ /dev/null @@ -1,4 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class BleIOBusyException extends Exception{ -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BleIOBusyException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BleIOBusyException.kt new file mode 100644 index 0000000000..6029d66998 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/BleIOBusyException.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +class BleIOBusyException : Exception() \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CharacteristicNotFoundException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CharacteristicNotFoundException.java deleted file mode 100644 index 1405d93f32..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CharacteristicNotFoundException.java +++ /dev/null @@ -1,7 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class CharacteristicNotFoundException extends FailedToConnectException { - public CharacteristicNotFoundException(String cmdCharacteristicUuid) { - super("characteristic not found: " + cmdCharacteristicUuid); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CharacteristicNotFoundException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CharacteristicNotFoundException.kt new file mode 100644 index 0000000000..730b6eeda0 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CharacteristicNotFoundException.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +class CharacteristicNotFoundException(cmdCharacteristicUuid: String) : FailedToConnectException("characteristic not found: $cmdCharacteristicUuid") \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmDescriptorWriteException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmDescriptorWriteException.java deleted file mode 100644 index b2034fd087..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmDescriptorWriteException.java +++ /dev/null @@ -1,12 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class CouldNotConfirmDescriptorWriteException extends Exception{ - private final String received; - private final String expected; - - public CouldNotConfirmDescriptorWriteException(String received, String expected) { - super(); - this.received = received; - this.expected = expected; - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmDescriptorWriteException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmDescriptorWriteException.kt new file mode 100644 index 0000000000..0b49f74970 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmDescriptorWriteException.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +class CouldNotConfirmDescriptorWriteException(private val received: String, private val expected: String) : Exception() \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmWrite.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmWrite.java deleted file mode 100644 index f422746180..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmWrite.java +++ /dev/null @@ -1,13 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class CouldNotConfirmWrite extends Exception { - - private final byte[] sent; - private final Object confirmed; - - public CouldNotConfirmWrite(byte[] sent, byte[] confirmed) { - super(); - this.sent = sent; - this.confirmed = confirmed; - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmWrite.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmWrite.kt new file mode 100644 index 0000000000..cb815ce34c --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotConfirmWrite.kt @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +class CouldNotConfirmWrite(private val sent: ByteArray, confirmed: ByteArray) : Exception() { + + private val confirmed: Any + + init { + this.confirmed = confirmed + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotEnableNotifications.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotEnableNotifications.java deleted file mode 100644 index 261490dee5..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotEnableNotifications.java +++ /dev/null @@ -1,9 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType; - -public class CouldNotEnableNotifications extends Exception { - public CouldNotEnableNotifications(CharacteristicType cmd) { - super(cmd.getValue()); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotEnableNotifications.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotEnableNotifications.kt new file mode 100644 index 0000000000..7564ab32e1 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotEnableNotifications.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType + +class CouldNotEnableNotifications(cmd: CharacteristicType) : Exception(cmd.value) \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendBleException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendBleException.java deleted file mode 100644 index 6bd30f5ff8..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendBleException.java +++ /dev/null @@ -1,7 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class CouldNotSendBleException extends Exception { - public CouldNotSendBleException(String msg) { - super(msg); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendBleException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendBleException.kt new file mode 100644 index 0000000000..63abcb9a68 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotSendBleException.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +class CouldNotSendBleException(msg: String?) : Exception(msg) \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DescriptorNotFoundException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DescriptorNotFoundException.java deleted file mode 100644 index d7dc3473eb..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DescriptorNotFoundException.java +++ /dev/null @@ -1,4 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class DescriptorNotFoundException extends Exception { -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DescriptorNotFoundException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DescriptorNotFoundException.kt new file mode 100644 index 0000000000..202fcaf3b1 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DescriptorNotFoundException.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +class DescriptorNotFoundException : Exception() \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DiscoveredInvalidPodException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DiscoveredInvalidPodException.java deleted file mode 100644 index 9de20faf07..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DiscoveredInvalidPodException.java +++ /dev/null @@ -1,11 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -import android.os.ParcelUuid; - -import java.util.List; - -public class DiscoveredInvalidPodException extends Exception { - public DiscoveredInvalidPodException(String message, List serviceUUIds) { - super(message + " service UUIDs: " + serviceUUIds); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DiscoveredInvalidPodException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DiscoveredInvalidPodException.kt new file mode 100644 index 0000000000..9b8ff7488d --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/DiscoveredInvalidPodException.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +import android.os.ParcelUuid + +class DiscoveredInvalidPodException(message: String, serviceUUIds: List) : Exception("$message service UUIDs: $serviceUUIds") \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.java deleted file mode 100644 index dd4cf724ed..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.java +++ /dev/null @@ -1,11 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class FailedToConnectException extends Exception { - public FailedToConnectException() { - super(); - } - - public FailedToConnectException(String message) { - super(message); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.kt new file mode 100644 index 0000000000..c720724ceb --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/FailedToConnectException.kt @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +open class FailedToConnectException : Exception { + constructor() : super() {} + constructor(message: String?) : super(message) {} +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailException.java deleted file mode 100644 index f99fbe32d4..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailException.java +++ /dev/null @@ -1,10 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class ScanFailException extends Exception { - public ScanFailException() { - } - - public ScanFailException(int errorCode) { - super("errorCode" + errorCode); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailException.kt new file mode 100644 index 0000000000..6c6dcc2f49 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailException.kt @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +open class ScanFailException : Exception { + constructor() {} + constructor(errorCode: Int) : super("errorCode$errorCode") {} +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.java deleted file mode 100644 index 7fc00ae2df..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.java +++ /dev/null @@ -1,20 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.BleDiscoveredDevice; - -public class ScanFailFoundTooManyException extends ScanFailException { - private final List devices; - - public ScanFailFoundTooManyException(List devices) { - super(); - this.devices = new ArrayList<>(devices); - } - - public List getDiscoveredDevices() { - return Collections.unmodifiableList(this.devices); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.kt new file mode 100644 index 0000000000..d83b6643e8 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailFoundTooManyException.kt @@ -0,0 +1,15 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.BleDiscoveredDevice +import java.util.* + +class ScanFailFoundTooManyException(devices: List?) : ScanFailException() { + + private val devices: List + val discoveredDevices: List + get() = Collections.unmodifiableList(devices) + + init { + this.devices = ArrayList(devices) + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailNotFoundException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailNotFoundException.java deleted file mode 100644 index 9bf2284db3..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailNotFoundException.java +++ /dev/null @@ -1,4 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class ScanFailNotFoundException extends ScanFailException { -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailNotFoundException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailNotFoundException.kt new file mode 100644 index 0000000000..9466ea9b52 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ScanFailNotFoundException.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +class ScanFailNotFoundException : ScanFailException() \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ServiceNotFoundException.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ServiceNotFoundException.java deleted file mode 100644 index 51bfa5b8ef..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ServiceNotFoundException.java +++ /dev/null @@ -1,7 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions; - -public class ServiceNotFoundException extends FailedToConnectException { - public ServiceNotFoundException(String serviceUuid) { - super("service not found: " + serviceUuid); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ServiceNotFoundException.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ServiceNotFoundException.kt new file mode 100644 index 0000000000..dc792f5825 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/ServiceNotFoundException.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +class ServiceNotFoundException(serviceUuid: String) : FailedToConnectException("service not found: $serviceUuid") \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.java deleted file mode 100644 index 75490b33e3..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.java +++ /dev/null @@ -1,140 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io; - -import android.bluetooth.BluetoothGatt; -import android.bluetooth.BluetoothGattCharacteristic; -import android.bluetooth.BluetoothGattDescriptor; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.BleIOBusyException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmDescriptorWriteException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmWrite; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotEnableNotifications; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotSendBleException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.DescriptorNotFoundException; - - -public class BleIO { - private static final int DEFAULT_IO_TIMEOUT_MS = 1000; - - private final AAPSLogger aapsLogger; - private final Map chars; - private final Map> incomingPackets; - private final BluetoothGatt gatt; - private final BleCommCallbacks bleCommCallbacks; - - private IOState state; - - public BleIO(AAPSLogger aapsLogger, Map chars, Map> incomingPackets, BluetoothGatt gatt, BleCommCallbacks bleCommCallbacks) { - this.aapsLogger = aapsLogger; - this.chars = chars; - this.incomingPackets = incomingPackets; - this.gatt = gatt; - this.bleCommCallbacks = bleCommCallbacks; - this.state = IOState.IDLE; - } - - /*** - * - * @param characteristic where to read from(CMD or DATA) - * @return a byte array with the received data - */ - public byte[] receivePacket(CharacteristicType characteristic) throws - BleIOBusyException, - InterruptedException, - TimeoutException { - synchronized (this.state) { - if (this.state != IOState.IDLE) { - throw new BleIOBusyException(); - } - this.state = IOState.READING; - } - byte[] ret = this.incomingPackets.get(characteristic).poll(DEFAULT_IO_TIMEOUT_MS, TimeUnit.MILLISECONDS); - if (ret == null) { - throw new TimeoutException(); - } - synchronized (this.state) { - this.state = IOState.IDLE; - } - return ret; - } - - /*** - * - * @param characteristic where to write to(CMD or DATA) - * @param payload the data to send - * @throws CouldNotSendBleException - */ - public void sendAndConfirmPacket(CharacteristicType characteristic, byte[] payload) - throws CouldNotSendBleException, - BleIOBusyException, - InterruptedException, - CouldNotConfirmWrite, - TimeoutException { - synchronized (this.state) { - if (this.state != IOState.IDLE) { - throw new BleIOBusyException(); - } - this.state = IOState.WRITING; - } - - aapsLogger.debug(LTag.PUMPBTCOMM, "BleIO: Sending data on" + characteristic.name() + "/" + payload.toString()); - BluetoothGattCharacteristic ch = chars.get(characteristic); - boolean set = ch.setValue(payload); - if (!set) { - throw new CouldNotSendBleException("setValue"); - } - boolean sent = this.gatt.writeCharacteristic(ch); - if (!sent) { - throw new CouldNotSendBleException("writeCharacteristic"); - } - this.bleCommCallbacks.confirmWrite(CharacteristicType.CMD, payload, DEFAULT_IO_TIMEOUT_MS); - synchronized (this.state) { - this.state = IOState.IDLE; - } - } - - /** - * Called before sending a new message. - * The incoming queues should be empty, so we log when they are not. - */ - public void flushIncomingQueues() { - - } - - /** - * Enable intentions on the characteristics. - * This will signal the pod it can start sending back data - * @return - */ - public void readyToRead() - throws CouldNotSendBleException, - CouldNotEnableNotifications, - DescriptorNotFoundException, - InterruptedException, CouldNotConfirmDescriptorWriteException { - - for (CharacteristicType type : CharacteristicType.values()) { - BluetoothGattCharacteristic ch = this.chars.get(type); - boolean notificationSet = this.gatt.setCharacteristicNotification(ch, true); - if (!notificationSet) { - throw new CouldNotEnableNotifications(type); - } - List descriptors = ch.getDescriptors(); - if (descriptors.size() != 1) { - throw new DescriptorNotFoundException(); - } - BluetoothGattDescriptor descriptor = descriptors.get(0); - descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); - gatt.writeDescriptor(descriptor); - bleCommCallbacks.confirmWriteDescriptor(descriptor.getUuid().toString(), DEFAULT_IO_TIMEOUT_MS); - } - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.kt new file mode 100644 index 0000000000..7dfe2a44b4 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/BleIO.kt @@ -0,0 +1,104 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io + +import android.bluetooth.BluetoothGatt +import android.bluetooth.BluetoothGattCharacteristic +import android.bluetooth.BluetoothGattDescriptor +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.* +import java.util.concurrent.BlockingQueue +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +class BleIO(private val aapsLogger: AAPSLogger, private val chars: Map, private val incomingPackets: Map>, private val gatt: BluetoothGatt, private val bleCommCallbacks: BleCommCallbacks) { + + private var state: IOState + + /*** + * + * @param characteristic where to read from(CMD or DATA) + * @return a byte array with the received data + */ + @Throws(BleIOBusyException::class, InterruptedException::class, TimeoutException::class) + fun receivePacket(characteristic: CharacteristicType): ByteArray { + synchronized(state) { + if (state != IOState.IDLE) { + throw BleIOBusyException() + } + state = IOState.READING + } + val ret = incomingPackets[characteristic]!!.poll(DEFAULT_IO_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS) + ?: throw TimeoutException() + synchronized(state) { state = IOState.IDLE } + return ret + } + + /*** + * + * @param characteristic where to write to(CMD or DATA) + * @param payload the data to send + * @throws CouldNotSendBleException + */ + @Throws(CouldNotSendBleException::class, BleIOBusyException::class, InterruptedException::class, CouldNotConfirmWrite::class, TimeoutException::class) + fun sendAndConfirmPacket(characteristic: CharacteristicType, payload: ByteArray) { + synchronized(state) { + if (state != IOState.IDLE) { + throw BleIOBusyException() + } + state = IOState.WRITING + } + aapsLogger.debug(LTag.PUMPBTCOMM, "BleIO: Sending data on" + characteristic.name + "/" + payload.toString()) + val ch = chars[characteristic] + val set = ch!!.setValue(payload) + if (!set) { + throw CouldNotSendBleException("setValue") + } + val sent = gatt.writeCharacteristic(ch) + if (!sent) { + throw CouldNotSendBleException("writeCharacteristic") + } + bleCommCallbacks.confirmWrite(payload, DEFAULT_IO_TIMEOUT_MS) + synchronized(state) { state = IOState.IDLE } + } + + /** + * Called before sending a new message. + * The incoming queues should be empty, so we log when they are not. + */ + fun flushIncomingQueues() {} + + /** + * Enable intentions on the characteristics. + * This will signal the pod it can start sending back data + * @return + */ + @Throws(CouldNotSendBleException::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, InterruptedException::class, CouldNotConfirmDescriptorWriteException::class) + fun readyToRead() { + for (type in CharacteristicType.values()) { + val ch = chars[type] + val notificationSet = gatt.setCharacteristicNotification(ch, true) + if (!notificationSet) { + throw CouldNotEnableNotifications(type) + } + val descriptors = ch!!.descriptors + if (descriptors.size != 1) { + throw DescriptorNotFoundException() + } + val descriptor = descriptors[0] + descriptor.value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE + gatt.writeDescriptor(descriptor) + bleCommCallbacks.confirmWriteDescriptor(descriptor.uuid.toString(), DEFAULT_IO_TIMEOUT_MS) + } + } + + companion object { + + private const val DEFAULT_IO_TIMEOUT_MS = 1000 + } + + init { + state = IOState.IDLE + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.java deleted file mode 100644 index cd9ae12297..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.java +++ /dev/null @@ -1,7 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io; - -public enum IOState { - IDLE, - WRITING, - READING; -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.kt new file mode 100644 index 0000000000..4ef49f6586 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io + +enum class IOState { + IDLE, WRITING, READING +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.kt similarity index 59% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.java rename to omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.kt index 54babad049..6e8e7de891 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/BlePacket.kt @@ -1,4 +1,3 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet; +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet -public class BlePacket { -} +class BlePacket \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.java deleted file mode 100644 index d4c0a19ef8..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.java +++ /dev/null @@ -1,94 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan; - -import android.bluetooth.le.ScanRecord; -import android.bluetooth.le.ScanResult; -import android.os.ParcelUuid; - -import java.util.List; - -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.DiscoveredInvalidPodException; - -public class BleDiscoveredDevice { - private final ScanResult scanResult; - private final long podID; - private final int sequenceNo; - private final long lotNo; - - public BleDiscoveredDevice(ScanResult scanResult, long searchPodID) - throws DiscoveredInvalidPodException { - - this.scanResult = scanResult; - this.podID = searchPodID; - - this.validateServiceUUIDs(); - this.validatePodID(); - this.lotNo = this.parseLotNo(); - this.sequenceNo = this.parseSeqNo(); - } - - private static String extractUUID16(ParcelUuid uuid) { - return uuid.toString().substring(4, 8); - } - - private void validateServiceUUIDs() - throws DiscoveredInvalidPodException { - ScanRecord scanRecord = scanResult.getScanRecord(); - List serviceUUIDs = scanRecord.getServiceUuids(); - - if (serviceUUIDs.size() != 9) { - throw new DiscoveredInvalidPodException("Expected 9 service UUIDs, got" + serviceUUIDs.size(), serviceUUIDs); - } - if (!extractUUID16(serviceUUIDs.get(0)).equals("4024")) { - // this is the service that we filtered for - throw new DiscoveredInvalidPodException("The first exposed service UUID should be 4024, got " + extractUUID16(serviceUUIDs.get(0)), serviceUUIDs); - } - // TODO understand what is serviceUUIDs[1]. 0x2470. Alarms? - if (!extractUUID16(serviceUUIDs.get(2)).equals("000a")) { - // constant? - throw new DiscoveredInvalidPodException("The third exposed service UUID should be 000a, got " + serviceUUIDs.get(2), serviceUUIDs); - } - } - - private void validatePodID() - throws DiscoveredInvalidPodException { - ScanRecord scanRecord = scanResult.getScanRecord(); - List serviceUUIDs = scanRecord.getServiceUuids(); - String hexPodID = extractUUID16(serviceUUIDs.get(3)) + extractUUID16(serviceUUIDs.get(4)); - Long podID = Long.parseLong(hexPodID, 16); - if (this.podID != podID) { - throw new DiscoveredInvalidPodException("This is not the POD we are looking for. " + this.podID + " found: " + podID, serviceUUIDs); - } - } - - private long parseLotNo() { - ScanRecord scanRecord = scanResult.getScanRecord(); - List serviceUUIDs = scanRecord.getServiceUuids(); - String lotSeq = extractUUID16(serviceUUIDs.get(5)) + - extractUUID16(serviceUUIDs.get(6)) + - extractUUID16(serviceUUIDs.get(7)); - - return Long.parseLong(lotSeq.substring(0, 10), 16); - } - - private int parseSeqNo() { - ScanRecord scanRecord = scanResult.getScanRecord(); - List serviceUUIDs = scanRecord.getServiceUuids(); - String lotSeq = extractUUID16(serviceUUIDs.get(7)) + - extractUUID16(serviceUUIDs.get(8)); - - return Integer.parseInt(lotSeq.substring(2), 16); - } - - public ScanResult getScanResult() { - return this.scanResult; - } - - @Override public String toString() { - return "BleDiscoveredDevice{" + - "scanResult=" + scanResult + - ", podID=" + podID + - ", sequenceNo=" + sequenceNo + - ", lotNo=" + lotNo + - '}'; - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.kt new file mode 100644 index 0000000000..dba4b8d8b5 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/BleDiscoveredDevice.kt @@ -0,0 +1,78 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan + +import android.bluetooth.le.ScanResult +import android.os.ParcelUuid +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.DiscoveredInvalidPodException + +class BleDiscoveredDevice(val scanResult: ScanResult, private val podID: Long) { + + private val sequenceNo: Int + private val lotNo: Long + @Throws(DiscoveredInvalidPodException::class) private fun validateServiceUUIDs() { + val scanRecord = scanResult.scanRecord + ?: throw DiscoveredInvalidPodException("Scan record is null") + val serviceUUIDs = scanRecord.serviceUuids + if (serviceUUIDs.size != 9) { + throw DiscoveredInvalidPodException("Expected 9 service UUIDs, got" + serviceUUIDs.size, serviceUUIDs) + } + if (extractUUID16(serviceUUIDs[0]) != "4024") { + // this is the service that we filtered for + throw DiscoveredInvalidPodException("The first exposed service UUID should be 4024, got " + extractUUID16(serviceUUIDs[0]), serviceUUIDs) + } + // TODO understand what is serviceUUIDs[1]. 0x2470. Alarms? + if (extractUUID16(serviceUUIDs[2]) != "000a") { + // constant? + throw DiscoveredInvalidPodException("The third exposed service UUID should be 000a, got " + serviceUUIDs[2], serviceUUIDs) + } + } + + @Throws(DiscoveredInvalidPodException::class) private fun validatePodID() { + val scanRecord = scanResult.scanRecord + val serviceUUIDs = scanRecord.serviceUuids + val hexPodID = extractUUID16(serviceUUIDs[3]) + extractUUID16(serviceUUIDs[4]) + val podID = hexPodID.toLong(16) + if (this.podID != podID) { + throw DiscoveredInvalidPodException("This is not the POD we are looking for. " + this.podID + " found: " + podID, serviceUUIDs) + } + } + + private fun parseLotNo(): Long { + val scanRecord = scanResult.scanRecord + val serviceUUIDs = scanRecord.serviceUuids + val lotSeq = extractUUID16(serviceUUIDs[5]) + + extractUUID16(serviceUUIDs[6]) + + extractUUID16(serviceUUIDs[7]) + return lotSeq.substring(0, 10).toLong(16) + } + + private fun parseSeqNo(): Int { + val scanRecord = scanResult.scanRecord + val serviceUUIDs = scanRecord.serviceUuids + val lotSeq = extractUUID16(serviceUUIDs[7]) + + extractUUID16(serviceUUIDs[8]) + return lotSeq.substring(2).toInt(16) + } + + override fun toString(): String { + return "BleDiscoveredDevice{" + + "scanResult=" + scanResult + + ", podID=" + podID + + ", sequenceNo=" + sequenceNo + + ", lotNo=" + lotNo + + '}' + } + + companion object { + + private fun extractUUID16(uuid: ParcelUuid): String { + return uuid.toString().substring(4, 8) + } + } + + init { + validateServiceUUIDs() + validatePodID() + lotNo = parseLotNo() + sequenceNo = parseSeqNo() + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.java deleted file mode 100644 index c3953f75d1..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.java +++ /dev/null @@ -1,62 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan; - -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.le.BluetoothLeScanner; -import android.bluetooth.le.ScanFilter; -import android.bluetooth.le.ScanSettings; -import android.os.ParcelUuid; - -import java.util.Arrays; -import java.util.List; - -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailFoundTooManyException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailNotFoundException; - -public class PodScanner { - public static final String SCAN_FOR_SERVICE_UUID = "00004024-0000-1000-8000-00805F9B34FB"; - public static final long POD_ID_NOT_ACTIVATED = 4294967294L; - private static final int SCAN_DURATION_MS = 5000; - - private final BluetoothAdapter bluetoothAdapter; - private final AAPSLogger logger; - - public PodScanner(AAPSLogger logger, BluetoothAdapter bluetoothAdapter) { - this.bluetoothAdapter = bluetoothAdapter; - this.logger = logger; - } - - public BleDiscoveredDevice scanForPod(String serviceUUID, long podID) - throws InterruptedException, ScanFailException { - BluetoothLeScanner scanner = this.bluetoothAdapter.getBluetoothLeScanner(); - - ScanFilter filter = new ScanFilter.Builder() - .setServiceUuid(ParcelUuid.fromString(serviceUUID)) - .build(); - - ScanSettings scanSettings = new ScanSettings.Builder() - .setLegacy(false) - .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) - .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) - .build(); - - ScanCollector scanCollector = new ScanCollector(this.logger, podID); - this.logger.debug(LTag.PUMPBTCOMM, "Scanning with filters: "+ filter.toString() + " settings" + scanSettings.toString()); - scanner.startScan(Arrays.asList(filter), scanSettings, scanCollector); - - Thread.sleep(SCAN_DURATION_MS); - - scanner.flushPendingScanResults(scanCollector); - scanner.stopScan(scanCollector); - - List collected = scanCollector.collect(); - if (collected.size() == 0) { - throw new ScanFailNotFoundException(); - } else if (collected.size() > 1) { - throw new ScanFailFoundTooManyException(collected); - } - return collected.get(0); - } -} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.kt new file mode 100644 index 0000000000..829faaa405 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/PodScanner.kt @@ -0,0 +1,48 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan + +import android.bluetooth.BluetoothAdapter +import android.bluetooth.le.ScanFilter +import android.bluetooth.le.ScanSettings +import android.os.ParcelUuid +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailFoundTooManyException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailNotFoundException +import java.util.* + +class PodScanner(private val logger: AAPSLogger, private val bluetoothAdapter: BluetoothAdapter) { + + @Throws(InterruptedException::class, ScanFailException::class) + fun scanForPod(serviceUUID: String?, podID: Long): BleDiscoveredDevice { + val scanner = bluetoothAdapter.bluetoothLeScanner + val filter = ScanFilter.Builder() + .setServiceUuid(ParcelUuid.fromString(serviceUUID)) + .build() + val scanSettings = ScanSettings.Builder() + .setLegacy(false) + .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) + .build() + val scanCollector = ScanCollector(logger, podID) + logger.debug(LTag.PUMPBTCOMM, "Scanning with filters: $filter settings$scanSettings") + scanner.startScan(Arrays.asList(filter), scanSettings, scanCollector) + Thread.sleep(SCAN_DURATION_MS.toLong()) + scanner.flushPendingScanResults(scanCollector) + scanner.stopScan(scanCollector) + val collected = scanCollector.collect() + if (collected.size == 0) { + throw ScanFailNotFoundException() + } else if (collected.size > 1) { + throw ScanFailFoundTooManyException(collected) + } + return collected[0] + } + + companion object { + + const val SCAN_FOR_SERVICE_UUID = "00004024-0000-1000-8000-00805F9B34FB" + const val POD_ID_NOT_ACTIVATED = 4294967294L + private const val SCAN_DURATION_MS = 5000 + } +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.java deleted file mode 100644 index 9121b0f5a4..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.java +++ /dev/null @@ -1,66 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan; - -import android.bluetooth.le.ScanCallback; -import android.bluetooth.le.ScanResult; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.DiscoveredInvalidPodException; -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailException; - -public class ScanCollector extends ScanCallback { - private final AAPSLogger logger; - private final long podID; - // there could be different threads calling the onScanResult callback - private final ConcurrentHashMap found; - private int scanFailed; - - public ScanCollector(AAPSLogger logger, long podID) { - this.podID = podID; - this.logger = logger; - this.found = new ConcurrentHashMap(); - } - - @Override - public void onScanResult(int callbackType, ScanResult result) { - // callbackType will be ALL - this.logger.debug(LTag.PUMPBTCOMM, "Scan found: "+result.toString()); - this.found.put(result.getDevice().getAddress(), result); - } - - @Override - public void onScanFailed(int errorCode) { - this.scanFailed = errorCode; - this.logger.warn(LTag.PUMPBTCOMM, "Scan failed with errorCode: "+errorCode); - super.onScanFailed(errorCode); - } - - public List collect() - throws ScanFailException { - List ret = new ArrayList<>(); - - if (this.scanFailed != 0) { - throw new ScanFailException(this.scanFailed); - } - - logger.debug(LTag.PUMPBTCOMM, "ScanCollector looking for podID: " + this.podID); - - for (ScanResult result : this.found.values()) { - try { - BleDiscoveredDevice device = new BleDiscoveredDevice(result, this.podID); - ret.add(device); - logger.debug(LTag.PUMPBTCOMM, "ScanCollector found: " + result.toString() + "Pod ID: " + this.podID); - } catch (DiscoveredInvalidPodException e) { - logger.debug(LTag.PUMPBTCOMM, "ScanCollector: pod not matching" + e.toString()); - // this is not the POD we are looking for - } - } - return Collections.unmodifiableList(ret); - } -} - diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.kt new file mode 100644 index 0000000000..d37f714854 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/scan/ScanCollector.kt @@ -0,0 +1,51 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan + +import android.bluetooth.le.ScanCallback +import android.bluetooth.le.ScanResult +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.DiscoveredInvalidPodException +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailException +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +class ScanCollector(private val logger: AAPSLogger, private val podID: Long) : ScanCallback() { + + // there could be different threads calling the onScanResult callback + private val found: ConcurrentHashMap + private var scanFailed = 0 + override fun onScanResult(callbackType: Int, result: ScanResult) { + // callbackType will be ALL + logger.debug(LTag.PUMPBTCOMM, "Scan found: $result") + found[result.device.address] = result + } + + override fun onScanFailed(errorCode: Int) { + scanFailed = errorCode + logger.warn(LTag.PUMPBTCOMM, "Scan failed with errorCode: $errorCode") + super.onScanFailed(errorCode) + } + + @Throws(ScanFailException::class) fun collect(): List { + val ret: MutableList = ArrayList() + if (scanFailed != 0) { + throw ScanFailException(scanFailed) + } + logger.debug(LTag.PUMPBTCOMM, "ScanCollector looking for podID: " + podID) + for (result in found.values) { + try { + val device = BleDiscoveredDevice(result, podID) + ret.add(device) + logger.debug(LTag.PUMPBTCOMM, "ScanCollector found: " + result.toString() + "Pod ID: " + podID) + } catch (e: DiscoveredInvalidPodException) { + logger.debug(LTag.PUMPBTCOMM, "ScanCollector: pod not matching$e") + // this is not the POD we are looking for + } + } + return Collections.unmodifiableList(ret) + } + + init { + found = ConcurrentHashMap() + } +} \ No newline at end of file