ktlint format

This commit is contained in:
AdrianLxM 2021-03-01 13:39:02 +01:00
parent 3ebcc1c71e
commit 77c816e813
146 changed files with 557 additions and 467 deletions

View file

@ -30,7 +30,9 @@ class DashHistoryTest {
fun setUp() { fun setUp() {
val context = ApplicationProvider.getApplicationContext<Context>() val context = ApplicationProvider.getApplicationContext<Context>()
database = Room.inMemoryDatabaseBuilder( database = Room.inMemoryDatabaseBuilder(
context, DashHistoryDatabase::class.java).build() context,
DashHistoryDatabase::class.java
).build()
dao = database.historyRecordDao() dao = database.historyRecordDao()
dashHistory = DashHistory(dao, HistoryMapper()) dashHistory = DashHistory(dao, HistoryMapper())
} }

View file

@ -26,7 +26,6 @@ class RxSchedulerRule(val scheduler: Scheduler) : TestRule {
RxJavaPlugins.reset() RxJavaPlugins.reset()
RxAndroidPlugins.reset() RxAndroidPlugins.reset()
} }
} }
} }
} }

View file

@ -29,5 +29,4 @@ class OmnipodDashHistoryModule {
@Singleton @Singleton
internal fun provideDashHistory(dao: HistoryRecordDao, historyMapper: HistoryMapper) = internal fun provideDashHistory(dao: HistoryRecordDao, historyMapper: HistoryMapper) =
DashHistory(dao, historyMapper) DashHistory(dao, historyMapper)
} }

View file

@ -50,7 +50,8 @@ class OmnipodDashManagerImpl @Inject constructor(
private fun observeSendProgramBolusCommand(units: Double, rateInEighthPulsesPerSeconds: Byte, confirmationBeeps: Boolean, completionBeeps: Boolean): Observable<PodEvent> { private fun observeSendProgramBolusCommand(units: Double, rateInEighthPulsesPerSeconds: Byte, confirmationBeeps: Boolean, completionBeeps: Boolean): Observable<PodEvent> {
return Observable.defer { return Observable.defer {
bleManager.sendCommand(ProgramBolusCommand.Builder() bleManager.sendCommand(
ProgramBolusCommand.Builder()
.setUniqueId(podStateManager.uniqueId!!.toInt()) .setUniqueId(podStateManager.uniqueId!!.toInt())
.setSequenceNumber(podStateManager.messageSequenceNumber) .setSequenceNumber(podStateManager.messageSequenceNumber)
.setNonce(1229869870) // TODO .setNonce(1229869870) // TODO
@ -78,13 +79,15 @@ class OmnipodDashManagerImpl @Inject constructor(
get() = Observable.defer { get() = Observable.defer {
observeSendGetPodStatusCommand() observeSendGetPodStatusCommand()
.ignoreElements() // .ignoreElements() //
.andThen(Observable.defer { .andThen(
Observable.defer {
if (podStateManager.podStatus == PodStatus.RUNNING_ABOVE_MIN_VOLUME) { if (podStateManager.podStatus == PodStatus.RUNNING_ABOVE_MIN_VOLUME) {
Observable.empty() Observable.empty()
} else { } else {
Observable.error(IllegalStateException("Unexpected Pod status")) Observable.error(IllegalStateException("Unexpected Pod status"))
} }
}) }
)
} }
private fun observeSendProgramAlertsCommand(alertConfigurations: List<AlertConfiguration>, multiCommandFlag: Boolean = false): Observable<PodEvent> { private fun observeSendProgramAlertsCommand(alertConfigurations: List<AlertConfiguration>, multiCommandFlag: Boolean = false): Observable<PodEvent> {
@ -119,32 +122,38 @@ class OmnipodDashManagerImpl @Inject constructor(
get() = Observable.defer { get() = Observable.defer {
observeSendGetPodStatusCommand() observeSendGetPodStatusCommand()
.ignoreElements() // .ignoreElements() //
.andThen(Observable.defer { .andThen(
Observable.defer {
if (podStateManager.podStatus == PodStatus.CLUTCH_DRIVE_ENGAGED) { if (podStateManager.podStatus == PodStatus.CLUTCH_DRIVE_ENGAGED) {
Observable.empty() Observable.empty()
} else { } else {
Observable.error(IllegalStateException("Unexpected Pod status")) Observable.error(IllegalStateException("Unexpected Pod status"))
} }
}) }
)
} }
private val observeSendSetUniqueIdCommand: Observable<PodEvent> private val observeSendSetUniqueIdCommand: Observable<PodEvent>
get() = Observable.defer { get() = Observable.defer {
bleManager.sendCommand(SetUniqueIdCommand.Builder() // bleManager.sendCommand(
SetUniqueIdCommand.Builder() //
.setSequenceNumber(podStateManager.messageSequenceNumber) // .setSequenceNumber(podStateManager.messageSequenceNumber) //
.setUniqueId(podStateManager.uniqueId!!.toInt()) // .setUniqueId(podStateManager.uniqueId!!.toInt()) //
.setLotNumber(podStateManager.lotNumber!!.toInt()) // .setLotNumber(podStateManager.lotNumber!!.toInt()) //
.setPodSequenceNumber(podStateManager.podSequenceNumber!!.toInt()) .setPodSequenceNumber(podStateManager.podSequenceNumber!!.toInt())
.setInitializationTime(Date()) .setInitializationTime(Date())
.build()) // .build()
) //
} }
private val observeSendGetVersionCommand: Observable<PodEvent> private val observeSendGetVersionCommand: Observable<PodEvent>
get() = Observable.defer { get() = Observable.defer {
bleManager.sendCommand(GetVersionCommand.Builder() // bleManager.sendCommand(
GetVersionCommand.Builder() //
.setSequenceNumber(podStateManager.messageSequenceNumber) // .setSequenceNumber(podStateManager.messageSequenceNumber) //
.setUniqueId(DEFAULT_UNIQUE_ID) // .setUniqueId(DEFAULT_UNIQUE_ID) //
.build()) // .build()
) //
} }
override fun activatePodPart1(lowReservoirAlertTrigger: AlertTrigger.ReservoirVolumeTrigger?): Observable<PodEvent> { override fun activatePodPart1(lowReservoirAlertTrigger: AlertTrigger.ReservoirVolumeTrigger?): Observable<PodEvent> {
@ -277,7 +286,8 @@ class OmnipodDashManagerImpl @Inject constructor(
) )
} }
if (podStateManager.activationProgress.isBefore(ActivationProgress.UPDATED_EXPIRATION_ALERTS)) { if (podStateManager.activationProgress.isBefore(ActivationProgress.UPDATED_EXPIRATION_ALERTS)) {
observables.add(observeSendProgramAlertsCommand( observables.add(
observeSendProgramAlertsCommand(
listOf( listOf(
// FIXME use user configured expiration alert // FIXME use user configured expiration alert
AlertConfiguration( AlertConfiguration(
@ -300,7 +310,8 @@ class OmnipodDashManagerImpl @Inject constructor(
) )
), ),
multiCommandFlag = true multiCommandFlag = true
).doOnComplete(ActivationProgressUpdater(ActivationProgress.UPDATED_EXPIRATION_ALERTS))) ).doOnComplete(ActivationProgressUpdater(ActivationProgress.UPDATED_EXPIRATION_ALERTS))
)
} }
if (podStateManager.activationProgress.isBefore(ActivationProgress.PROGRAMMED_BASAL)) { if (podStateManager.activationProgress.isBefore(ActivationProgress.PROGRAMMED_BASAL)) {
observables.add( observables.add(
@ -424,7 +435,6 @@ class OmnipodDashManagerImpl @Inject constructor(
} }
} }
} }
} }
inner class ErrorInterceptor : Consumer<Throwable> { inner class ErrorInterceptor : Consumer<Throwable> {
@ -432,7 +442,6 @@ class OmnipodDashManagerImpl @Inject constructor(
override fun accept(throwable: Throwable) { override fun accept(throwable: Throwable) {
logger.debug(LTag.PUMP, "Intercepted error in OmnipodDashManagerImpl: ${throwable.javaClass.simpleName}") logger.debug(LTag.PUMP, "Intercepted error in OmnipodDashManagerImpl: ${throwable.javaClass.simpleName}")
} }
} }
inner class ActivationProgressUpdater(private val value: ActivationProgress) : Action { inner class ActivationProgressUpdater(private val value: ActivationProgress) : Action {
@ -440,6 +449,5 @@ class OmnipodDashManagerImpl @Inject constructor(
override fun run() { override fun run() {
podStateManager.activationProgress = value podStateManager.activationProgress = value
} }
} }
} }

View file

@ -22,7 +22,7 @@ data class Id(val address: ByteArray) {
override fun toString(): String { override fun toString(): String {
val asInt = ByteBuffer.wrap(address).int val asInt = ByteBuffer.wrap(address).int
return "${asInt}/${address.toHex()}" return "$asInt/${address.toHex()}"
} }
companion object { companion object {
@ -33,5 +33,4 @@ data class Id(val address: ByteArray) {
return Id(ByteBuffer.allocate(4).putInt(v).array()) return Id(ByteBuffer.allocate(4).putInt(v).array())
} }
} }
} }

View file

@ -39,8 +39,10 @@ class OmnipodDashBleManagerImpl @Inject constructor(private val context: Context
// TODO: locking? // TODO: locking?
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress) val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
val incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>> = val incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>> =
mapOf(CharacteristicType.CMD to LinkedBlockingDeque(), mapOf(
CharacteristicType.DATA to LinkedBlockingDeque()) CharacteristicType.CMD to LinkedBlockingDeque(),
CharacteristicType.DATA to LinkedBlockingDeque()
)
val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets) val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets)
aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to $podAddress") aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to $podAddress")
var autoConnect = true var autoConnect = true
@ -118,5 +120,4 @@ class OmnipodDashBleManagerImpl @Inject constructor(private val context: Context
private const val CONNECT_TIMEOUT_MS = 7000 private const val CONNECT_TIMEOUT_MS = 7000
const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else. const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else.
} }
} }

View file

@ -4,7 +4,6 @@ import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCharacteristic import android.bluetooth.BluetoothGattCharacteristic
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag 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.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.CharacteristicNotFoundException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ServiceNotFoundException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ServiceNotFoundException
@ -29,8 +28,10 @@ class ServiceDiscoverer(private val logger: AAPSLogger, private val gatt: Blueto
?: throw CharacteristicNotFoundException(CharacteristicType.CMD.value) ?: throw CharacteristicNotFoundException(CharacteristicType.CMD.value)
val dataChar = service.getCharacteristic(CharacteristicType.DATA.uuid) // TODO: this is never used val dataChar = service.getCharacteristic(CharacteristicType.DATA.uuid) // TODO: this is never used
?: throw CharacteristicNotFoundException(CharacteristicType.DATA.value) ?: throw CharacteristicNotFoundException(CharacteristicType.DATA.value)
var chars = mapOf(CharacteristicType.CMD to cmdChar, var chars = mapOf(
CharacteristicType.DATA to dataChar) CharacteristicType.CMD to cmdChar,
CharacteristicType.DATA to dataChar
)
return chars return chars
} }

View file

@ -77,8 +77,11 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
} else { } else {
CharacteristicWriteConfirmationError(status) CharacteristicWriteConfirmationError(status)
} }
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite with status/char/value " + aapsLogger.debug(
status + "/" + byValue(characteristic.uuid.toString()) + "/" + characteristic.value.toHex()) LTag.PUMPBTCOMM,
"OnCharacteristicWrite with status/char/value " +
status + "/" + byValue(characteristic.uuid.toString()) + "/" + characteristic.value.toHex()
)
try { try {
if (writeQueue.size > 0) { if (writeQueue.size > 0) {
aapsLogger.warn(LTag.PUMPBTCOMM, "Write confirm queue should be empty. found: " + writeQueue.size) aapsLogger.warn(LTag.PUMPBTCOMM, "Write confirm queue should be empty. found: " + writeQueue.size)
@ -97,9 +100,12 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
super.onCharacteristicChanged(gatt, characteristic) super.onCharacteristicChanged(gatt, characteristic)
val payload = characteristic.value val payload = characteristic.value
val characteristicType = byValue(characteristic.uuid.toString()) val characteristicType = byValue(characteristic.uuid.toString())
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicChanged with char/value " + aapsLogger.debug(
LTag.PUMPBTCOMM,
"OnCharacteristicChanged with char/value " +
characteristicType + "/" + characteristicType + "/" +
payload.toHex()) payload.toHex()
)
incomingPackets[characteristicType]!!.add(payload) incomingPackets[characteristicType]!!.add(payload)
} }
@ -109,7 +115,8 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
?: throw TimeoutException() ?: throw TimeoutException()
when (confirmed) { when (confirmed) {
is DescriptorWriteConfirmationError -> throw CouldNotConfirmWriteException(confirmed.status) is DescriptorWriteConfirmationError -> throw CouldNotConfirmWriteException(confirmed.status)
is DescriptorWriteConfirmationUUID -> if (confirmed.uuid != descriptorUUID) { is DescriptorWriteConfirmationUUID ->
if (confirmed.uuid != descriptorUUID) {
aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm descriptor write. Got ${confirmed.uuid}. Expected: $descriptorUUID") aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm descriptor write. Got ${confirmed.uuid}. Expected: $descriptorUUID")
throw CouldNotConfirmDescriptorWriteException(descriptorUUID, confirmed.uuid) throw CouldNotConfirmDescriptorWriteException(descriptorUUID, confirmed.uuid)
} else { } else {

View file

@ -2,7 +2,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command
import java.nio.ByteBuffer import java.nio.ByteBuffer
class BleCommandHello(controllerId: Int) : BleCommand(BleCommandType.HELLO, class BleCommandHello(controllerId: Int) : BleCommand(
BleCommandType.HELLO,
ByteBuffer.allocate(6) ByteBuffer.allocate(6)
.put(1.toByte()) // TODO find the meaning of this constant .put(1.toByte()) // TODO find the meaning of this constant
.put(4.toByte()) // TODO find the meaning of this constant .put(4.toByte()) // TODO find the meaning of this constant

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
class CouldNotConfirmDescriptorWriteException(override val message: String?) : Exception(message) { class CouldNotConfirmDescriptorWriteException(override val message: String?) : Exception(message) {
constructor(sent: String, confirmed: String) : this("Could not confirm write. Sent: {$sent} .Received: ${confirmed}") constructor(sent: String, confirmed: String) : this("Could not confirm write. Sent: {$sent} .Received: $confirmed")
constructor(status: Int) : this("Could not confirm write. Write status: ${status}") constructor(status: Int) : this("Could not confirm write. Write status: $status")
} }

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
class CouldNotConfirmWriteException(override val message: String?) : Exception(message) { class CouldNotConfirmWriteException(override val message: String?) : Exception(message) {
constructor(sent: ByteArray, confirmed: ByteArray) : this("Could not confirm write. Sent: {$sent} .Received: ${confirmed}") constructor(sent: ByteArray, confirmed: ByteArray) : this("Could not confirm write. Sent: {$sent} .Received: $confirmed")
constructor(status: Int) : this("Could not confirm write. Write status: ${status}") constructor(status: Int) : this("Could not confirm write. Write status: $status")
} }

View file

@ -2,4 +2,4 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.excepti
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommand import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommand
class UnexpectedCommandException(val cmd: BleCommand) : Exception("Unexpected command: ${cmd}") class UnexpectedCommandException(val cmd: BleCommand) : Exception("Unexpected command: $cmd")

View file

@ -3,4 +3,4 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
import info.nightscout.androidaps.utils.extensions.toHex import info.nightscout.androidaps.utils.extensions.toHex
class CrcMismatchException(val expected: Long, val actual: Long, val payload: ByteArray) : class CrcMismatchException(val expected: Long, val actual: Long, val payload: ByteArray) :
Exception("CRC mismatch. Actual: ${actual}. Expected: ${expected}. Payload: ${payload.toHex()}") Exception("CRC mismatch. Actual: $actual. Expected: $expected. Payload: ${payload.toHex()}")

View file

@ -2,4 +2,4 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
import info.nightscout.androidaps.utils.extensions.toHex import info.nightscout.androidaps.utils.extensions.toHex
class IncorrectPacketException(val expectedIndex: Byte, val payload: ByteArray) : Exception("Invalid payload: ${payload.toHex()}. Expected index: ${expectedIndex}") class IncorrectPacketException(val expectedIndex: Byte, val payload: ByteArray) : Exception("Invalid payload: ${payload.toHex()}. Expected index: $expectedIndex")

View file

@ -21,7 +21,8 @@ data class MessagePacket(
val gateway: Boolean = false, val gateway: Boolean = false,
val sas: Boolean = false, // TODO: understand val sas: Boolean = false, // TODO: understand
val tfs: Boolean = false, // TODO: understand val tfs: Boolean = false, // TODO: understand
val version: Short = 0.toShort()) { val version: Short = 0.toShort()
) {
fun asByteArray(): ByteArray { fun asByteArray(): ByteArray {
val bb = ByteBuffer.allocate(16 + payload.size) val bb = ByteBuffer.allocate(16 + payload.size)
@ -139,7 +140,6 @@ private class Flag(var value: Int = 0) {
return 0 return 0
} }
return 1 return 1
} }
} }

View file

@ -103,7 +103,6 @@ class PayloadJoiner(private val firstPacket: ByteArray) {
} }
return bytes.copyOfRange(0, bytes.size) return bytes.copyOfRange(0, bytes.size)
} }
} }
internal fun Int.toUnsignedLong() = this.toLong() and 0xffffffffL internal fun Int.toUnsignedLong() = this.toLong() and 0xffffffffL

View file

@ -15,51 +15,63 @@ internal class PayloadSplitter(private val payload: ByteArray) {
val crc32 = payload.crc32() val crc32 = payload.crc32()
if (payload.size <= FirstBlePacket.CAPACITY_WITH_THE_OPTIONAL_PLUS_ONE_PACKET) { if (payload.size <= FirstBlePacket.CAPACITY_WITH_THE_OPTIONAL_PLUS_ONE_PACKET) {
val end = min(FirstBlePacket.CAPACITY_WITHOUT_MIDDLE_PACKETS, payload.size) val end = min(FirstBlePacket.CAPACITY_WITHOUT_MIDDLE_PACKETS, payload.size)
ret.add(FirstBlePacket( ret.add(
FirstBlePacket(
totalFragments = 0, totalFragments = 0,
payload = payload.copyOfRange(0, end), payload = payload.copyOfRange(0, end),
size = payload.size.toByte(), size = payload.size.toByte(),
crc32 = crc32, crc32 = crc32,
)) )
)
if (payload.size > FirstBlePacket.CAPACITY_WITHOUT_MIDDLE_PACKETS) { if (payload.size > FirstBlePacket.CAPACITY_WITHOUT_MIDDLE_PACKETS) {
ret.add(LastOptionalPlusOneBlePacket( ret.add(
LastOptionalPlusOneBlePacket(
index = 1, index = 1,
payload = payload.copyOfRange(end, payload.size), payload = payload.copyOfRange(end, payload.size),
size = (payload.size - end).toByte(), size = (payload.size - end).toByte(),
)) )
)
} }
return ret return ret
} }
val middleFragments = (payload.size - FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS) / MiddleBlePacket.CAPACITY val middleFragments = (payload.size - FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS) / MiddleBlePacket.CAPACITY
val rest = ((payload.size - middleFragments * MiddleBlePacket.CAPACITY) - FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS).toByte() val rest = ((payload.size - middleFragments * MiddleBlePacket.CAPACITY) - FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS).toByte()
ret.add(FirstBlePacket( ret.add(
FirstBlePacket(
totalFragments = (middleFragments + 1).toByte(), totalFragments = (middleFragments + 1).toByte(),
payload = payload.copyOfRange(0, FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS), payload = payload.copyOfRange(0, FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS),
)) )
)
for (i in 1..middleFragments) { for (i in 1..middleFragments) {
val p = if (i == 1) { val p = if (i == 1) {
payload.copyOfRange(FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS, FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + MiddleBlePacket.CAPACITY) payload.copyOfRange(FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS, FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + MiddleBlePacket.CAPACITY)
} else { } else {
payload.copyOfRange(FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + (i - 1) * MiddleBlePacket.CAPACITY, FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + i * MiddleBlePacket.CAPACITY) payload.copyOfRange(FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + (i - 1) * MiddleBlePacket.CAPACITY, FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + i * MiddleBlePacket.CAPACITY)
} }
ret.add(MiddleBlePacket( ret.add(
MiddleBlePacket(
index = i.toByte(), index = i.toByte(),
payload = p, payload = p,
)) )
)
} }
val end = min(LastBlePacket.CAPACITY, rest.toInt()) val end = min(LastBlePacket.CAPACITY, rest.toInt())
ret.add(LastBlePacket( ret.add(
LastBlePacket(
index = (middleFragments + 1).toByte(), index = (middleFragments + 1).toByte(),
size = rest, size = rest,
payload = payload.copyOfRange(middleFragments * MiddleBlePacket.CAPACITY + FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS, middleFragments * MiddleBlePacket.CAPACITY + FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + end), payload = payload.copyOfRange(middleFragments * MiddleBlePacket.CAPACITY + FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS, middleFragments * MiddleBlePacket.CAPACITY + FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + end),
crc32 = crc32, crc32 = crc32,
)) )
)
if (rest > LastBlePacket.CAPACITY) { if (rest > LastBlePacket.CAPACITY) {
ret.add(LastOptionalPlusOneBlePacket( ret.add(
LastOptionalPlusOneBlePacket(
index = (middleFragments + 2).toByte(), index = (middleFragments + 2).toByte(),
size = (rest - LastBlePacket.CAPACITY).toByte(), size = (rest - LastBlePacket.CAPACITY).toByte(),
payload = payload.copyOfRange(middleFragments * MiddleBlePacket.CAPACITY + FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + LastBlePacket.CAPACITY, payload.size), payload = payload.copyOfRange(middleFragments * MiddleBlePacket.CAPACITY + FirstBlePacket.CAPACITY_WITH_MIDDLE_PACKETS + LastBlePacket.CAPACITY, payload.size),
)) )
)
} }
return ret return ret
} }

View file

@ -19,20 +19,20 @@ class StringLengthPrefixEncoding {
for ((index, key) in keys.withIndex()) { for ((index, key) in keys.withIndex()) {
when { when {
remaining.size < key.length -> remaining.size < key.length ->
throw MessageIOException("Payload too short: ${payload.toHex()} for key: ${key}") throw MessageIOException("Payload too short: ${payload.toHex()} for key: $key")
!(remaining.copyOfRange(0, key.length).decodeToString() == key) -> !(remaining.copyOfRange(0, key.length).decodeToString() == key) ->
throw MessageIOException("Key not found: ${key} in ${payload.toHex()}") throw MessageIOException("Key not found: $key in ${payload.toHex()}")
// last key can be empty, no length // last key can be empty, no length
index == keys.size - 1 && remaining.size == key.length -> index == keys.size - 1 && remaining.size == key.length ->
return ret return ret
remaining.size < key.length + LENGTH_BYTES -> remaining.size < key.length + LENGTH_BYTES ->
throw MessageIOException("Length not found: for ${key} in ${payload.toHex()}") throw MessageIOException("Length not found: for $key in ${payload.toHex()}")
} }
remaining = remaining.copyOfRange(key.length, remaining.size) remaining = remaining.copyOfRange(key.length, remaining.size)
val length = (remaining[0].toUnsignedInt() shl 1) or remaining[1].toUnsignedInt() val length = (remaining[0].toUnsignedInt() shl 1) or remaining[1].toUnsignedInt()
if (length > remaining.size) { if (length > remaining.size) {
throw MessageIOException("Payload too short, looking for length ${length} for ${key} in ${payload.toHex()}") throw MessageIOException("Payload too short, looking for length $length for $key in ${payload.toHex()}")
} }
ret[index] = remaining.copyOfRange(LENGTH_BYTES, LENGTH_BYTES + length) ret[index] = remaining.copyOfRange(LENGTH_BYTES, LENGTH_BYTES + length)
remaining = remaining.copyOfRange(LENGTH_BYTES + length, remaining.size) remaining = remaining.copyOfRange(LENGTH_BYTES + length, remaining.size)

View file

@ -92,4 +92,3 @@ data class LastOptionalPlusOneBlePacket(val index: Byte, val payload: ByteArray,
internal const val HEADER_SIZE = 2 internal const val HEADER_SIZE = 2
} }
} }

View file

@ -15,7 +15,6 @@ class BleDiscoveredDevice(val scanResult: ScanResult, private val scanRecord: Sc
val serviceUuids = scanRecord.serviceUuids val serviceUuids = scanRecord.serviceUuids
if (serviceUuids.size != 9) { if (serviceUuids.size != 9) {
throw DiscoveredInvalidPodException("Expected 9 service UUIDs, got" + serviceUuids.size, serviceUuids) throw DiscoveredInvalidPodException("Expected 9 service UUIDs, got" + serviceUuids.size, serviceUuids)
} }
if (extractUUID16(serviceUuids[0]) != MAIN_SERVICE_UUID) { if (extractUUID16(serviceUuids[0]) != MAIN_SERVICE_UUID) {
// this is the service that we filtered for // this is the service that we filtered for

View file

@ -45,5 +45,4 @@ class ScanCollector(private val logger: AAPSLogger, private val podID: Long) : S
} }
return Collections.unmodifiableList(ret) return Collections.unmodifiableList(ret)
} }
} }

View file

@ -20,4 +20,3 @@ sealed class PodEvent {
class CommandSent(val command: Command) : PodEvent() class CommandSent(val command: Command) : PodEvent()
class ResponseReceived(val response: Response) : PodEvent() class ResponseReceived(val response: Response) : PodEvent()
} }

View file

@ -13,12 +13,14 @@ class DeactivateCommand private constructor(
) : NonceEnabledCommand(CommandType.DEACTIVATE, uniqueId, sequenceNumber, multiCommandFlag, nonce) { ) : NonceEnabledCommand(CommandType.DEACTIVATE, uniqueId, sequenceNumber, multiCommandFlag, nonce) {
override val encoded: ByteArray override val encoded: ByteArray
get() = appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // get() = appendCrc(
ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) // .put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
.put(commandType.value) // .put(commandType.value) //
.put(BODY_LENGTH) // .put(BODY_LENGTH) //
.putInt(nonce) // .putInt(nonce) //
.array()) .array()
)
override fun toString(): String = "DeactivateCommand{" + override fun toString(): String = "DeactivateCommand{" +
"nonce=" + nonce + "nonce=" + nonce +

View file

@ -14,12 +14,14 @@ class GetStatusCommand private constructor(
) : HeaderEnabledCommand(CommandType.GET_STATUS, uniqueId, sequenceNumber, multiCommandFlag) { ) : HeaderEnabledCommand(CommandType.GET_STATUS, uniqueId, sequenceNumber, multiCommandFlag) {
override val encoded: ByteArray override val encoded: ByteArray
get() = appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // get() = appendCrc(
ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) // .put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
.put(commandType.value) // .put(commandType.value) //
.put(BODY_LENGTH) // .put(BODY_LENGTH) //
.put(statusResponseType.value) // .put(statusResponseType.value) //
.array()) .array()
)
class Builder : HeaderEnabledCommandBuilder<Builder, GetStatusCommand>() { class Builder : HeaderEnabledCommandBuilder<Builder, GetStatusCommand>() {
@ -35,7 +37,6 @@ class GetStatusCommand private constructor(
return GetStatusCommand(uniqueId!!, sequenceNumber!!, multiCommandFlag, statusResponseType!!) return GetStatusCommand(uniqueId!!, sequenceNumber!!, multiCommandFlag, statusResponseType!!)
} }
} }
companion object { companion object {

View file

@ -12,12 +12,14 @@ class GetVersionCommand private constructor(
) : HeaderEnabledCommand(CommandType.GET_VERSION, uniqueId, sequenceNumber, multiCommandFlag) { ) : HeaderEnabledCommand(CommandType.GET_VERSION, uniqueId, sequenceNumber, multiCommandFlag) {
override val encoded: ByteArray override val encoded: ByteArray
get() = appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // get() = appendCrc(
ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) // .put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
.put(commandType.value) // .put(commandType.value) //
.put(BODY_LENGTH) // .put(BODY_LENGTH) //
.putInt(uniqueId) // .putInt(uniqueId) //
.array()) .array()
)
override fun toString(): String { override fun toString(): String {
return "GetVersionCommand{" + return "GetVersionCommand{" +

View file

@ -49,11 +49,13 @@ class ProgramBasalCommand private constructor(
val basalCommand = buffer.array() val basalCommand = buffer.array()
val interlockCommand = interlockCommand.encoded val interlockCommand = interlockCommand.encoded
val header: ByteArray = encodeHeader(uniqueId, sequenceNumber, (basalCommand.size + interlockCommand.size).toShort(), multiCommandFlag) val header: ByteArray = encodeHeader(uniqueId, sequenceNumber, (basalCommand.size + interlockCommand.size).toShort(), multiCommandFlag)
return appendCrc(ByteBuffer.allocate(basalCommand.size + interlockCommand.size + header.size) // return appendCrc(
ByteBuffer.allocate(basalCommand.size + interlockCommand.size + header.size) //
.put(header) // .put(header) //
.put(interlockCommand) // .put(interlockCommand) //
.put(basalCommand) // .put(basalCommand) //
.array()) .array()
)
} }
override fun toString(): String { override fun toString(): String {
@ -102,12 +104,16 @@ class ProgramBasalCommand private constructor(
val longInsulinProgramElements: List<BasalInsulinProgramElement> = mapTenthPulsesPerSlotToLongInsulinProgramElements(ProgramBasalUtil.mapBasalProgramToTenthPulsesPerSlot(basalProgram!!)) val longInsulinProgramElements: List<BasalInsulinProgramElement> = mapTenthPulsesPerSlotToLongInsulinProgramElements(ProgramBasalUtil.mapBasalProgramToTenthPulsesPerSlot(basalProgram!!))
val shortInsulinProgramElements = ProgramBasalUtil.mapPulsesPerSlotToShortInsulinProgramElements(pulsesPerSlot) val shortInsulinProgramElements = ProgramBasalUtil.mapPulsesPerSlotToShortInsulinProgramElements(pulsesPerSlot)
val currentBasalInsulinProgramElement = ProgramBasalUtil.calculateCurrentLongInsulinProgramElement(longInsulinProgramElements, currentTime) val currentBasalInsulinProgramElement = ProgramBasalUtil.calculateCurrentLongInsulinProgramElement(longInsulinProgramElements, currentTime)
val interlockCommand = ProgramInsulinCommand(uniqueId!!, sequenceNumber!!, multiCommandFlag, nonce!!, val interlockCommand = ProgramInsulinCommand(
uniqueId!!, sequenceNumber!!, multiCommandFlag, nonce!!,
shortInsulinProgramElements, checksum, currentSlot.index, currentSlot.eighthSecondsRemaining, shortInsulinProgramElements, checksum, currentSlot.index, currentSlot.eighthSecondsRemaining,
currentSlot.pulsesRemaining, ProgramInsulinCommand.DeliveryType.BASAL) currentSlot.pulsesRemaining, ProgramInsulinCommand.DeliveryType.BASAL
return ProgramBasalCommand(interlockCommand, uniqueId!!, sequenceNumber!!, multiCommandFlag, )
return ProgramBasalCommand(
interlockCommand, uniqueId!!, sequenceNumber!!, multiCommandFlag,
longInsulinProgramElements, programReminder!!, currentBasalInsulinProgramElement.index, longInsulinProgramElements, programReminder!!, currentBasalInsulinProgramElement.index,
currentBasalInsulinProgramElement.remainingTenthPulses, currentBasalInsulinProgramElement.delayUntilNextTenthPulseInUsec) currentBasalInsulinProgramElement.remainingTenthPulses, currentBasalInsulinProgramElement.delayUntilNextTenthPulseInUsec
)
} }
} }

View file

@ -18,7 +18,8 @@ class ProgramBeepsCommand private constructor(
) : HeaderEnabledCommand(CommandType.PROGRAM_BEEPS, uniqueId, sequenceNumber, multiCommandFlag) { ) : HeaderEnabledCommand(CommandType.PROGRAM_BEEPS, uniqueId, sequenceNumber, multiCommandFlag) {
override val encoded: ByteArray override val encoded: ByteArray
get() = appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // get() = appendCrc(
ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) // .put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
.put(commandType.value) // .put(commandType.value) //
.put(BODY_LENGTH) // .put(BODY_LENGTH) //
@ -26,7 +27,8 @@ class ProgramBeepsCommand private constructor(
.put(basalReminder.encoded) // .put(basalReminder.encoded) //
.put(tempBasalReminder.encoded) // .put(tempBasalReminder.encoded) //
.put(bolusReminder.encoded) // .put(bolusReminder.encoded) //
.array()) .array()
)
class Builder : HeaderEnabledCommandBuilder<Builder, ProgramBeepsCommand>() { class Builder : HeaderEnabledCommandBuilder<Builder, ProgramBeepsCommand>() {

View file

@ -32,11 +32,13 @@ class ProgramBolusCommand private constructor(
.array() .array()
val interlockCommand = interlockCommand.encoded val interlockCommand = interlockCommand.encoded
val header: ByteArray = encodeHeader(uniqueId, sequenceNumber, (bolusCommand.size + interlockCommand.size).toShort(), multiCommandFlag) val header: ByteArray = encodeHeader(uniqueId, sequenceNumber, (bolusCommand.size + interlockCommand.size).toShort(), multiCommandFlag)
return appendCrc(ByteBuffer.allocate(header.size + interlockCommand.size + bolusCommand.size) // return appendCrc(
ByteBuffer.allocate(header.size + interlockCommand.size + bolusCommand.size) //
.put(header) // .put(header) //
.put(interlockCommand) // .put(interlockCommand) //
.put(bolusCommand) // .put(bolusCommand) //
.array()) .array()
)
} }
override fun toString(): String { override fun toString(): String {
@ -82,8 +84,10 @@ class ProgramBolusCommand private constructor(
val numberOfPulses = Math.round(numberOfUnits!! * 20).toShort() val numberOfPulses = Math.round(numberOfUnits!! * 20).toShort()
val byte10And11 = (numberOfPulses * delayBetweenPulsesInEighthSeconds!!).toShort() val byte10And11 = (numberOfPulses * delayBetweenPulsesInEighthSeconds!!).toShort()
val interlockCommand = ProgramInsulinCommand(uniqueId!!, sequenceNumber!!, multiCommandFlag, nonce!!, listOf(BolusShortInsulinProgramElement(numberOfPulses)), calculateChecksum(0x01.toByte(), byte10And11, numberOfPulses), val interlockCommand = ProgramInsulinCommand(
0x01.toByte(), byte10And11, numberOfPulses, ProgramInsulinCommand.DeliveryType.BOLUS) uniqueId!!, sequenceNumber!!, multiCommandFlag, nonce!!, listOf(BolusShortInsulinProgramElement(numberOfPulses)), calculateChecksum(0x01.toByte(), byte10And11, numberOfPulses),
0x01.toByte(), byte10And11, numberOfPulses, ProgramInsulinCommand.DeliveryType.BOLUS
)
val delayUntilFirstTenthPulseInUsec = delayBetweenPulsesInEighthSeconds!! / 8 * 100000 val delayUntilFirstTenthPulseInUsec = delayBetweenPulsesInEighthSeconds!! / 8 * 100000
return ProgramBolusCommand(interlockCommand, uniqueId!!, sequenceNumber!!, multiCommandFlag, programReminder!!, (numberOfPulses * 10).toShort(), delayUntilFirstTenthPulseInUsec) return ProgramBolusCommand(interlockCommand, uniqueId!!, sequenceNumber!!, multiCommandFlag, programReminder!!, (numberOfPulses * 10).toShort(), delayUntilFirstTenthPulseInUsec)
} }
@ -94,12 +98,14 @@ class ProgramBolusCommand private constructor(
private const val LENGTH: Short = 15 private const val LENGTH: Short = 15
private const val BODY_LENGTH: Byte = 13 private const val BODY_LENGTH: Byte = 13
private fun calculateChecksum(numberOfSlots: Byte, byte10And11: Short, numberOfPulses: Short): Short { private fun calculateChecksum(numberOfSlots: Byte, byte10And11: Short, numberOfPulses: Short): Short {
return MessageUtil.calculateChecksum(ByteBuffer.allocate(7) // return MessageUtil.calculateChecksum(
ByteBuffer.allocate(7) //
.put(numberOfSlots) // .put(numberOfSlots) //
.putShort(byte10And11) // .putShort(byte10And11) //
.putShort(numberOfPulses) // .putShort(numberOfPulses) //
.putShort(numberOfPulses) // .putShort(numberOfPulses) //
.array()) .array()
)
} }
} }
} }

View file

@ -11,7 +11,8 @@ class ProgramInsulinCommand internal constructor(
uniqueId: Int, uniqueId: Int,
sequenceNumber: Short, sequenceNumber: Short,
multiCommandFlag: Boolean, multiCommandFlag: Boolean,
nonce: Int, insulinProgramElements: nonce: Int,
insulinProgramElements:
List<ShortInsulinProgramElement>, List<ShortInsulinProgramElement>,
private val checksum: Short, private val checksum: Short,
private val byte9: Byte, private val byte9: Byte,

View file

@ -59,9 +59,11 @@ class ProgramTempBasalCommand private constructor(
val tenthPulsesPerSlot = ProgramTempBasalUtil.mapTempBasalToTenthPulsesPerSlot(durationInSlots.toInt(), rateInUnitsPerHour!!) val tenthPulsesPerSlot = ProgramTempBasalUtil.mapTempBasalToTenthPulsesPerSlot(durationInSlots.toInt(), rateInUnitsPerHour!!)
val shortInsulinProgramElements = ProgramTempBasalUtil.mapPulsesPerSlotToShortInsulinProgramElements(pulsesPerSlot) val shortInsulinProgramElements = ProgramTempBasalUtil.mapPulsesPerSlotToShortInsulinProgramElements(pulsesPerSlot)
val insulinProgramElements = ProgramTempBasalUtil.mapTenthPulsesPerSlotToLongInsulinProgramElements(tenthPulsesPerSlot) val insulinProgramElements = ProgramTempBasalUtil.mapTenthPulsesPerSlotToLongInsulinProgramElements(tenthPulsesPerSlot)
val interlockCommand = ProgramInsulinCommand(uniqueId!!, sequenceNumber!!, multiCommandFlag, nonce!!, shortInsulinProgramElements, val interlockCommand = ProgramInsulinCommand(
uniqueId!!, sequenceNumber!!, multiCommandFlag, nonce!!, shortInsulinProgramElements,
ProgramTempBasalUtil.calculateChecksum(durationInSlots, pulsesPerSlot[0], pulsesPerSlot), durationInSlots, ProgramTempBasalUtil.calculateChecksum(durationInSlots, pulsesPerSlot[0], pulsesPerSlot), durationInSlots,
0x3840.toShort(), pulsesPerSlot[0], ProgramInsulinCommand.DeliveryType.TEMP_BASAL) 0x3840.toShort(), pulsesPerSlot[0], ProgramInsulinCommand.DeliveryType.TEMP_BASAL
)
return ProgramTempBasalCommand(interlockCommand, uniqueId!!, sequenceNumber!!, multiCommandFlag, programReminder!!, insulinProgramElements) return ProgramTempBasalCommand(interlockCommand, uniqueId!!, sequenceNumber!!, multiCommandFlag, programReminder!!, insulinProgramElements)
} }
} }
@ -91,10 +93,12 @@ class ProgramTempBasalCommand private constructor(
val tempBasalCommand = buffer.array() val tempBasalCommand = buffer.array()
val interlockCommand = interlockCommand.encoded val interlockCommand = interlockCommand.encoded
val header: ByteArray = encodeHeader(uniqueId, sequenceNumber, (tempBasalCommand.size + interlockCommand.size).toShort(), multiCommandFlag) val header: ByteArray = encodeHeader(uniqueId, sequenceNumber, (tempBasalCommand.size + interlockCommand.size).toShort(), multiCommandFlag)
return appendCrc(ByteBuffer.allocate(header.size + interlockCommand.size + tempBasalCommand.size) // return appendCrc(
ByteBuffer.allocate(header.size + interlockCommand.size + tempBasalCommand.size) //
.put(header) // .put(header) //
.put(interlockCommand) // .put(interlockCommand) //
.put(tempBasalCommand) // .put(tempBasalCommand) //
.array()) .array()
)
} }
} }

View file

@ -16,7 +16,8 @@ class SetUniqueIdCommand private constructor(
) : HeaderEnabledCommand(CommandType.SET_UNIQUE_ID, uniqueId, sequenceNumber, multiCommandFlag) { ) : HeaderEnabledCommand(CommandType.SET_UNIQUE_ID, uniqueId, sequenceNumber, multiCommandFlag) {
override val encoded: ByteArray override val encoded: ByteArray
get() = appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // get() = appendCrc(
ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
.put(encodeHeader(DEFAULT_UNIQUE_ID, sequenceNumber, LENGTH, multiCommandFlag)) // .put(encodeHeader(DEFAULT_UNIQUE_ID, sequenceNumber, LENGTH, multiCommandFlag)) //
.put(commandType.value) // .put(commandType.value) //
.put(BODY_LENGTH) // .put(BODY_LENGTH) //
@ -26,7 +27,8 @@ class SetUniqueIdCommand private constructor(
.put(encodeInitializationTime(initializationTime)) // .put(encodeInitializationTime(initializationTime)) //
.putInt(lotNumber) // .putInt(lotNumber) //
.putInt(podSequenceNumber) // .putInt(podSequenceNumber) //
.array()) .array()
)
override fun toString(): String { override fun toString(): String {
return "SetUniqueIdCommand{" + return "SetUniqueIdCommand{" +

View file

@ -18,13 +18,15 @@ class SilenceAlertsCommand private constructor(
override val encoded: ByteArray override val encoded: ByteArray
get() = get() =
appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // appendCrc(
ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) // .put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
.put(commandType.value) // .put(commandType.value) //
.put(BODY_LENGTH) // .put(BODY_LENGTH) //
.putInt(nonce) // .putInt(nonce) //
.put(AlertUtil.encodeAlertSet(alertTypes)) // .put(AlertUtil.encodeAlertSet(alertTypes)) //
.array()) .array()
)
override fun toString(): String { override fun toString(): String {
return "SilenceAlertsCommand{" + return "SilenceAlertsCommand{" +

View file

@ -19,13 +19,15 @@ class StopDeliveryCommand private constructor(
override val encoded: ByteArray override val encoded: ByteArray
get() { get() {
return appendCrc(ByteBuffer.allocate(LENGTH + HEADER_LENGTH) // return appendCrc(
ByteBuffer.allocate(LENGTH + HEADER_LENGTH) //
.put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) // .put(encodeHeader(uniqueId, sequenceNumber, LENGTH, multiCommandFlag)) //
.put(commandType.value) // .put(commandType.value) //
.put(BODY_LENGTH) // .put(BODY_LENGTH) //
.putInt(nonce) // .putInt(nonce) //
.put((beepType.value.toInt() shl 4 or deliveryType.encoded[0].toInt()).toByte()) // .put((beepType.value.toInt() shl 4 or deliveryType.encoded[0].toInt()).toByte()) //
.array()) .array()
)
} }
override fun toString(): String { override fun toString(): String {

View file

@ -11,9 +11,11 @@ class BasalShortInsulinProgramElement(
override val encoded: ByteArray override val encoded: ByteArray
get() { get() {
val firstByte = (numberOfSlots - 1 and 0x0f shl 4 // val firstByte = (
numberOfSlots - 1 and 0x0f shl 4 //
or ((if (extraAlternatePulse) 1 else 0) shl 3) // or ((if (extraAlternatePulse) 1 else 0) shl 3) //
or (pulsesPerSlot.toInt() ushr 8 and 0x03)).toByte() or (pulsesPerSlot.toInt() ushr 8 and 0x03)
).toByte()
return ByteBuffer.allocate(2) // return ByteBuffer.allocate(2) //
.put(firstByte) // .put(firstByte) //
.put((pulsesPerSlot and 0xff).toByte()) // .put((pulsesPerSlot and 0xff).toByte()) //

View file

@ -159,5 +159,4 @@ enum class AlarmType(override val value: Byte) : HasValue {
ALARM_BLE_QN_EXCEED_MAX_RETRY(0xc1.toByte()), ALARM_BLE_QN_EXCEED_MAX_RETRY(0xc1.toByte()),
ALARM_BLE_QN_CRIT_VAR_FAIL(0xc2.toByte()), ALARM_BLE_QN_CRIT_VAR_FAIL(0xc2.toByte()),
UNKNOWN(0xff.toByte()); UNKNOWN(0xff.toByte());
} }

View file

@ -29,7 +29,8 @@ class AlertConfiguration(
return ByteBuffer.allocate(6) // return ByteBuffer.allocate(6) //
.put(firstByte) .put(firstByte)
.put(durationInMinutes.toByte()) // .put(durationInMinutes.toByte()) //
.putShort(when (trigger) { .putShort(
when (trigger) {
is AlertTrigger.ReservoirVolumeTrigger -> { is AlertTrigger.ReservoirVolumeTrigger -> {
trigger.thresholdInMicroLiters trigger.thresholdInMicroLiters
} }
@ -37,7 +38,8 @@ class AlertConfiguration(
is AlertTrigger.TimerTrigger -> { is AlertTrigger.TimerTrigger -> {
trigger.offsetInMinutes trigger.offsetInMinutes
} }
}) // }
) //
.put(beepRepetition.value) // .put(beepRepetition.value) //
.put(beepType.value) // .put(beepType.value) //
.array() .array()

View file

@ -10,5 +10,4 @@ enum class BeepRepetitionType(
XXX3(0x05.toByte()), // Used in user pod expiration alert XXX3(0x05.toByte()), // Used in user pod expiration alert
XXX4(0x06.toByte()), // Used in pod expiration alert XXX4(0x06.toByte()), // Used in pod expiration alert
XXX5(0x08.toByte()); // Used in imminent pod expiration alert XXX5(0x08.toByte()); // Used in imminent pod expiration alert
} }

View file

@ -10,7 +10,11 @@ class ProgramReminder(
) : Encodable, Serializable { ) : Encodable, Serializable {
override val encoded: ByteArray override val encoded: ByteArray
get() = byteArrayOf(((if (atStart) 1 else 0) shl 7 get() = byteArrayOf(
(
(if (atStart) 1 else 0) shl 7
or ((if (atEnd) 1 else 0) shl 6) or ((if (atEnd) 1 else 0) shl 6)
or ((atInterval and 0x3f).toInt())).toByte()) or ((atInterval and 0x3f).toInt())
).toByte()
)
} }

View file

@ -84,5 +84,4 @@ class AlarmStatusResponse(
} }
infix fun Byte.shr(i: Int): Int = toInt() shr i infix fun Byte.shr(i: Int): Int = toInt() shr i
} }

View file

@ -34,7 +34,6 @@ class DefaultStatusResponse(
", minutesSinceActivation=$minutesSinceActivation" + ", minutesSinceActivation=$minutesSinceActivation" +
", reservoirPulsesRemaining=$reservoirPulsesRemaining)" ", reservoirPulsesRemaining=$reservoirPulsesRemaining)"
} }
} }
infix fun Byte.ushr(i: Int) = toInt() ushr i infix fun Byte.ushr(i: Int) = toInt() ushr i

View file

@ -6,5 +6,4 @@ abstract class ResponseBase(
) : Response { ) : Response {
override val encoded: ByteArray = encoded.copyOf(encoded.size) override val encoded: ByteArray = encoded.copyOf(encoded.size)
} }

View file

@ -55,5 +55,4 @@ class SetUniqueIdResponse(
", encoded=" + encoded.contentToString() + ", encoded=" + encoded.contentToString() +
'}' '}'
} }
} }

View file

@ -49,5 +49,4 @@ class VersionResponse(
", encoded=" + Arrays.toString(encoded) + ", encoded=" + Arrays.toString(encoded) +
'}' '}'
} }
} }

View file

@ -20,7 +20,8 @@ object AlertUtil {
} }
fun encodeAlertSet(alertSet: EnumSet<AlertType>): Byte = fun encodeAlertSet(alertSet: EnumSet<AlertType>): Byte =
alertSet.fold(0, alertSet.fold(
0,
{ out, slot -> { out, slot ->
out or (slot.value.toInt() and 0xff) out or (slot.value.toInt() and 0xff)
} }

View file

@ -44,7 +44,8 @@ class DashHistory @Inject constructor(
return Single.error(IllegalArgumentException("tempBasalRecord missing on SET_TEMPORARY_BASAL")) return Single.error(IllegalArgumentException("tempBasalRecord missing on SET_TEMPORARY_BASAL"))
} }
return dao.save(HistoryRecordEntity( return dao.save(
HistoryRecordEntity(
id = id, id = id,
date = date, date = date,
createdAt = currentTimeMillis(), createdAt = currentTimeMillis(),
@ -53,7 +54,8 @@ class DashHistory @Inject constructor(
bolusRecord = bolusRecord, bolusRecord = bolusRecord,
initialResult = initialResult, initialResult = initialResult,
resolvedResult = resolveResult, resolvedResult = resolveResult,
resolvedAt = resolvedAt) resolvedAt = resolvedAt
)
).toSingle { id } ).toSingle { id }
} }
@ -61,5 +63,4 @@ class DashHistory @Inject constructor(
dao.all().map { list -> list.map(historyMapper::entityToDomain) } dao.all().map { list -> list.map(historyMapper::entityToDomain) }
fun getRecordsAfter(time: Long): Single<List<HistoryRecordEntity>> = dao.allSince(time) fun getRecordsAfter(time: Long): Single<List<HistoryRecordEntity>> = dao.allSince(time)
} }

View file

@ -5,7 +5,6 @@ import androidx.room.Database
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.TypeConverters import androidx.room.TypeConverters
import androidx.room.migration.Migration
@Database( @Database(
entities = [HistoryRecordEntity::class], entities = [HistoryRecordEntity::class],
@ -26,5 +25,4 @@ abstract class DashHistoryDatabase : RoomDatabase() {
.fallbackToDestructiveMigration() .fallbackToDestructiveMigration()
.build() .build()
} }
} }

View file

@ -32,5 +32,4 @@ abstract class HistoryRecordDao {
@Query("UPDATE historyrecords SET resolvedResult = :resolvedResult, resolvedAt = :resolvedAt WHERE id = :id ") @Query("UPDATE historyrecords SET resolvedResult = :resolvedResult, resolvedAt = :resolvedAt WHERE id = :id ")
abstract fun markResolved(id: String, resolvedResult: ResolvedResult, resolvedAt: Long): Completable abstract fun markResolved(id: String, resolvedResult: ResolvedResult, resolvedAt: Long): Completable
} }

View file

@ -19,5 +19,5 @@ data class HistoryRecordEntity(
@Embedded(prefix = "tempBasalRecord_") val tempBasalRecord: TempBasalRecord?, @Embedded(prefix = "tempBasalRecord_") val tempBasalRecord: TempBasalRecord?,
@Embedded(prefix = "bolusRecord_") val bolusRecord: BolusRecord?, @Embedded(prefix = "bolusRecord_") val bolusRecord: BolusRecord?,
val resolvedResult: ResolvedResult?, val resolvedResult: ResolvedResult?,
val resolvedAt: Long?) val resolvedAt: Long?
)

View file

@ -21,7 +21,8 @@ class HistoryMapper {
) )
fun entityToDomain(entity: HistoryRecordEntity): HistoryRecord = fun entityToDomain(entity: HistoryRecordEntity): HistoryRecord =
HistoryRecord(id = entity.id, HistoryRecord(
id = entity.id,
createdAt = entity.createdAt, createdAt = entity.createdAt,
date = entity.date, date = entity.date,
initialResult = entity.initialResult, initialResult = entity.initialResult,
@ -30,5 +31,4 @@ class HistoryMapper {
resolvedResult = entity.resolvedResult, resolvedResult = entity.resolvedResult,
resolvedAt = entity.resolvedAt resolvedAt = entity.resolvedAt
) )
} }

View file

@ -66,10 +66,13 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() {
} }
binding.buttonDiscardPod.setOnClickListener { binding.buttonDiscardPod.setOnClickListener {
OKDialog.showConfirmation(this, OKDialog.showConfirmation(
resourceHelper.gs(R.string.omnipod_common_pod_management_discard_pod_confirmation), Thread { this,
resourceHelper.gs(R.string.omnipod_common_pod_management_discard_pod_confirmation),
Thread {
// TODO discard Pod // TODO discard Pod
}) }
)
} }
binding.buttonPlayTestBeep.setOnClickListener { binding.buttonPlayTestBeep.setOnClickListener {
@ -77,13 +80,16 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() {
binding.buttonPlayTestBeep.isEnabled = false binding.buttonPlayTestBeep.isEnabled = false
binding.buttonPlayTestBeep.setText(R.string.omnipod_common_pod_management_button_playing_test_beep) binding.buttonPlayTestBeep.setText(R.string.omnipod_common_pod_management_button_playing_test_beep)
commandQueue.customCommand(CommandPlayTestBeep(), object : Callback() { commandQueue.customCommand(
CommandPlayTestBeep(),
object : Callback() {
override fun run() { override fun run() {
if (!result.success) { if (!result.success) {
displayErrorDialog(resourceHelper.gs(R.string.omnipod_common_warning), resourceHelper.gs(R.string.omnipod_common_two_strings_concatenated_by_colon, resourceHelper.gs(R.string.omnipod_common_error_failed_to_play_test_beep), result.comment), false) displayErrorDialog(resourceHelper.gs(R.string.omnipod_common_warning), resourceHelper.gs(R.string.omnipod_common_two_strings_concatenated_by_colon, resourceHelper.gs(R.string.omnipod_common_error_failed_to_play_test_beep), result.comment), false)
} }
} }
}) }
)
} }
} }

View file

@ -107,38 +107,47 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
buttonBinding.buttonResumeDelivery.setOnClickListener { buttonBinding.buttonResumeDelivery.setOnClickListener {
disablePodActionButtons() disablePodActionButtons()
commandQueue.customCommand(CommandResumeDelivery(), commandQueue.customCommand(
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_resume_delivery), true).messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_delivery_resumed))) CommandResumeDelivery(),
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_resume_delivery), true).messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_delivery_resumed))
)
} }
buttonBinding.buttonRefreshStatus.setOnClickListener { buttonBinding.buttonRefreshStatus.setOnClickListener {
disablePodActionButtons() disablePodActionButtons()
commandQueue.readStatus("REQUESTED BY USER", commandQueue.readStatus(
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_refresh_status), false)) "REQUESTED BY USER",
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_refresh_status), false)
)
} }
buttonBinding.buttonSilenceAlerts.setOnClickListener { buttonBinding.buttonSilenceAlerts.setOnClickListener {
disablePodActionButtons() disablePodActionButtons()
commandQueue.customCommand(CommandAcknowledgeAlerts(), commandQueue.customCommand(
CommandAcknowledgeAlerts(),
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_silence_alerts), false) DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_silence_alerts), false)
.messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_silenced_alerts)) .messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_silenced_alerts))
.actionOnSuccess { rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_ALERTS)) }) .actionOnSuccess { rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_ALERTS)) }
)
} }
buttonBinding.buttonSuspendDelivery.setOnClickListener { buttonBinding.buttonSuspendDelivery.setOnClickListener {
disablePodActionButtons() disablePodActionButtons()
commandQueue.customCommand(CommandSuspendDelivery(), commandQueue.customCommand(
CommandSuspendDelivery(),
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_suspend_delivery), true) DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_suspend_delivery), true)
.messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_suspended_delivery))) .messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_suspended_delivery))
)
} }
buttonBinding.buttonSetTime.setOnClickListener { buttonBinding.buttonSetTime.setOnClickListener {
disablePodActionButtons() disablePodActionButtons()
commandQueue.customCommand(CommandHandleTimeChange(true), commandQueue.customCommand(
CommandHandleTimeChange(true),
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_set_time), true) DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_common_error_failed_to_set_time), true)
.messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_time_on_pod_updated))) .messageOnSuccess(resourceHelper.gs(R.string.omnipod_common_confirmation_time_on_pod_updated))
)
} }
} }
override fun onResume() { override fun onResume() {
@ -147,23 +156,32 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
disposables += rxBus disposables += rxBus
.toObservable(EventOmnipodDashPumpValuesChanged::class.java) .toObservable(EventOmnipodDashPumpValuesChanged::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribe({ .subscribe(
{
updateOmnipodStatus() updateOmnipodStatus()
updatePodActionButtons() updatePodActionButtons()
}, fabricPrivacy::logException) },
fabricPrivacy::logException
)
disposables += rxBus disposables += rxBus
.toObservable(EventQueueChanged::class.java) .toObservable(EventQueueChanged::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribe({ .subscribe(
{
updateQueueStatus() updateQueueStatus()
updatePodActionButtons() updatePodActionButtons()
}, fabricPrivacy::logException) },
fabricPrivacy::logException
)
disposables += rxBus disposables += rxBus
.toObservable(EventPreferenceChange::class.java) .toObservable(EventPreferenceChange::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribe({ .subscribe(
{
updatePodActionButtons() updatePodActionButtons()
}, fabricPrivacy::logException) },
fabricPrivacy::logException
)
updateUi() updateUi()
} }
@ -272,11 +290,13 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
val lowReservoirThreshold: Short = 20 val lowReservoirThreshold: Short = 20
podInfoBinding.reservoir.text = resourceHelper.gs(R.string.omnipod_common_overview_reservoir_value, podStateManager.pulsesRemaining) podInfoBinding.reservoir.text = resourceHelper.gs(R.string.omnipod_common_overview_reservoir_value, podStateManager.pulsesRemaining)
podInfoBinding.reservoir.setTextColor(if (podStateManager.pulsesRemaining!! < lowReservoirThreshold) { podInfoBinding.reservoir.setTextColor(
if (podStateManager.pulsesRemaining!! < lowReservoirThreshold) {
Color.RED Color.RED
} else { } else {
Color.WHITE Color.WHITE
}) }
)
} }
podInfoBinding.podActiveAlerts.text = if (podStateManager.activeAlerts!!.size > 0) { podInfoBinding.podActiveAlerts.text = if (podStateManager.activeAlerts!!.size > 0) {
@ -417,8 +437,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
} }
private fun updateRefreshStatusButton() { private fun updateRefreshStatusButton() {
buttonBinding.buttonRefreshStatus.isEnabled = podStateManager.isUniqueIdSet && podStateManager.activationProgress.isAtLeast(ActivationProgress.PHASE_1_COMPLETED) buttonBinding.buttonRefreshStatus.isEnabled = podStateManager.isUniqueIdSet && podStateManager.activationProgress.isAtLeast(ActivationProgress.PHASE_1_COMPLETED) &&
&& isQueueEmpty() isQueueEmpty()
} }
private fun updateResumeDeliveryButton() { private fun updateResumeDeliveryButton() {
@ -576,5 +596,4 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
return this return this
} }
} }
} }

View file

@ -12,5 +12,4 @@ class DashPodDeactivatedViewModel @Inject constructor() : PodDeactivatedViewMode
@StringRes @StringRes
override fun getTextId() = R.string.omnipod_common_pod_deactivation_wizard_pod_deactivated_text override fun getTextId() = R.string.omnipod_common_pod_deactivation_wizard_pod_deactivated_text
} }

View file

@ -1,8 +1,8 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertConfiguration
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertTrigger import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertTrigger
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepRepetitionType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepRepetitionType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType
import org.apache.commons.codec.DecoderException import org.apache.commons.codec.DecoderException

View file

@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlarmType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlarmType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.NakErrorType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.NakErrorType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType
import org.apache.commons.codec.DecoderException import org.apache.commons.codec.DecoderException
import org.apache.commons.codec.binary.Hex import org.apache.commons.codec.binary.Hex
import org.junit.Assert import org.junit.Assert

View file

@ -26,11 +26,13 @@ class FunctionsTest {
val value3 = Mockito.mock(ProfileValue::class.java) val value3 = Mockito.mock(ProfileValue::class.java)
value3.timeAsSeconds = 50400 value3.timeAsSeconds = 50400
value3.value = 3.05 value3.value = 3.05
PowerMockito.`when`(profile.basalValues).thenReturn(arrayOf( PowerMockito.`when`(profile.basalValues).thenReturn(
arrayOf(
value1, value1,
value2, value2,
value3 value3
)) )
)
val basalProgram: BasalProgram = mapProfileToBasalProgram(profile) val basalProgram: BasalProgram = mapProfileToBasalProgram(profile)
val entries: List<BasalProgram.Segment> = basalProgram.segments val entries: List<BasalProgram.Segment> = basalProgram.segments
assertEquals(3, entries.size) assertEquals(3, entries.size)
@ -69,8 +71,11 @@ class FunctionsTest {
val value = Mockito.mock(ProfileValue::class.java) val value = Mockito.mock(ProfileValue::class.java)
value.timeAsSeconds = 1800 value.timeAsSeconds = 1800
value.value = 0.5 value.value = 0.5
PowerMockito.`when`(profile.basalValues).thenReturn(arrayOf( PowerMockito.`when`(profile.basalValues).thenReturn(
value)) arrayOf(
value
)
)
mapProfileToBasalProgram(profile) mapProfileToBasalProgram(profile)
} }
@ -85,10 +90,12 @@ class FunctionsTest {
val value2 = Mockito.mock(ProfileValue::class.java) val value2 = Mockito.mock(ProfileValue::class.java)
value2.timeAsSeconds = 86400 value2.timeAsSeconds = 86400
value2.value = 0.5 value2.value = 0.5
PowerMockito.`when`(profile.basalValues).thenReturn(arrayOf( PowerMockito.`when`(profile.basalValues).thenReturn(
arrayOf(
value1, value1,
value2 value2
)) )
)
mapProfileToBasalProgram(profile) mapProfileToBasalProgram(profile)
} }
@ -99,8 +106,11 @@ class FunctionsTest {
val value = Mockito.mock(ProfileValue::class.java) val value = Mockito.mock(ProfileValue::class.java)
value.timeAsSeconds = -1 value.timeAsSeconds = -1
value.value = 0.5 value.value = 0.5
PowerMockito.`when`(profile.basalValues).thenReturn(arrayOf( PowerMockito.`when`(profile.basalValues).thenReturn(
value)) arrayOf(
value
)
)
mapProfileToBasalProgram(profile) mapProfileToBasalProgram(profile)
} }
@ -109,8 +119,11 @@ class FunctionsTest {
val value = Mockito.mock(ProfileValue::class.java) val value = Mockito.mock(ProfileValue::class.java)
value.timeAsSeconds = 0 value.timeAsSeconds = 0
value.value = 0.04 value.value = 0.04
PowerMockito.`when`(profile.basalValues).thenReturn(arrayOf( PowerMockito.`when`(profile.basalValues).thenReturn(
value)) arrayOf(
value
)
)
val basalProgram: BasalProgram = mapProfileToBasalProgram(profile) val basalProgram: BasalProgram = mapProfileToBasalProgram(profile)
val basalProgramElement: BasalProgram.Segment = basalProgram.segments[0] val basalProgramElement: BasalProgram.Segment = basalProgram.segments[0]
assertEquals(5, basalProgramElement.basalRateInHundredthUnitsPerHour) assertEquals(5, basalProgramElement.basalRateInHundredthUnitsPerHour)