Skip to content

Commit

Permalink
Merge pull request #2 from 0pen-dash/ble-io
Browse files Browse the repository at this point in the history
Ble updates
  • Loading branch information
bartsopers committed Feb 25, 2021
2 parents 5b43c3e + 9b7d31b commit 80788c4
Show file tree
Hide file tree
Showing 46 changed files with 690 additions and 535 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.content.Context
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.omnipod.dash.BuildConfig
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommandHello
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.BleIO
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner
import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingDeque
import java.util.concurrent.TimeoutException
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class BleManager @Inject constructor(private val context: Context, private val aapsLogger: AAPSLogger) : OmnipodDashCommunicationManager {

private val bluetoothManager: BluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter

@Throws(InterruptedException::class, ScanFailException::class, FailedToConnectException::class, CouldNotSendBleException::class, BleIOBusyException::class, TimeoutException::class, CouldNotConfirmWriteException::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class)
fun activateNewPod() {
aapsLogger.info(LTag.PUMPBTCOMM, "starting new pod activation")
val podScanner = PodScanner(aapsLogger, bluetoothAdapter)
val podAddress = podScanner.scanForPod(PodScanner.SCAN_FOR_SERVICE_UUID, PodScanner.POD_ID_NOT_ACTIVATED).scanResult.device.address
// For tests: this.podAddress = "B8:27:EB:1D:7E:BB";
connect(podAddress)
}

@Throws(FailedToConnectException::class, CouldNotSendBleException::class, InterruptedException::class, BleIOBusyException::class, TimeoutException::class, CouldNotConfirmWriteException::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class)
private fun connect(podAddress: String) {
// TODO: locking?
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
val incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>> =
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)
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()
val bleIO = BleIO(aapsLogger, chars, incomingPackets, gatt, bleCommCallbacks)
aapsLogger.debug(LTag.PUMPBTCOMM, "Saying hello to the pod")
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandHello(CONTROLLER_ID).data)
bleIO.readyToRead()
}

companion object {

private const val CONNECT_TIMEOUT_MS = 5000
private const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else.
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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 =
values().firstOrNull { it.value == value }
?: throw IllegalArgumentException("Unknown Characteristic Type: $value")
}
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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.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<CharacteristicType, BluetoothGattCharacteristic> {
logger.debug(LTag.PUMPBTCOMM, "Discovering services")
gatt.discoverServices()
bleCallbacks.waitForServiceDiscovery(DISCOVER_SERVICES_TIMEOUT_MS)
logger.debug(LTag.PUMPBTCOMM, "Services discovered")
val service = gatt.getService(SERVICE_UUID.toUuid())
?: throw ServiceNotFoundException(SERVICE_UUID)
val cmdChar = service.getCharacteristic(CharacteristicType.CMD.uuid)
?: throw CharacteristicNotFoundException(CharacteristicType.CMD.value)
val dataChar = service.getCharacteristic(CharacteristicType.DATA.uuid) // TODO: this is never used
?: throw CharacteristicNotFoundException(CharacteristicType.DATA.value)
var chars = mapOf(CharacteristicType.CMD to cmdChar,
CharacteristicType.DATA to dataChar)
return chars
}


private fun String.toUuid(): UUID = UUID(
BigInteger(replace("-", "").substring(0, 16), 16).toLong(),
BigInteger(replace("-", "").substring(16), 16).toLong()
)

companion object {
private const val SERVICE_UUID = "1a7e-4024-e3ed-4464-8b7e-751e03d0dc5f"
private const val DISCOVER_SERVICES_TIMEOUT_MS = 5000
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 80788c4

Please sign in to comment.