Moved sequence counter to BLEComm

This commit is contained in:
jbr7rr 2023-05-25 14:53:53 +02:00
parent 3027c2ffa5
commit c2e1017d73
4 changed files with 31 additions and 101 deletions

View file

@ -3,26 +3,24 @@ package info.nightscout.pump.medtrum.comm
import info.nightscout.pump.medtrum.encryption.Crypt
class WriteCommandPackets() {
class WriteCommandPackets(data: ByteArray, sequenceNumber: Int) {
private val CRC_8_TABLE: IntArray = intArrayOf(0, 155, 173, 54, 193, 90, 108, 247, 25, 130, 180, 47, 216, 67, 117, 238, 50, 169, 159, 4, 243, 104, 94, 197, 43, 176, 134, 29, 234, 113, 71, 220, 100, 255, 201, 82, 165, 62, 8, 147, 125, 230, 208, 75, 188, 39, 17, 138, 86, 205, 251, 96, 151, 12, 58, 161, 79, 212, 226, 121, 142, 21, 35, 184, 200, 83, 101, 254, 9, 146, 164, 63, 209, 74, 124, 231, 16, 139, 189, 38, 250, 97, 87, 204, 59, 160, 150, 13, 227, 120, 78, 213, 34, 185, 143, 20, 172, 55, 1, 154, 109, 246, 192, 91, 181, 46, 24, 131, 116, 239, 217, 66, 158, 5, 51, 168, 95, 196, 242, 105, 135, 28, 42, 177, 70, 221, 235, 112, 11, 144, 166, 61, 202, 81, 103, 252, 18, 137, 191, 36, 211, 72, 126, 229, 57, 162, 148, 15, 248, 99, 85, 206, 32, 187, 141, 22, 225, 122, 76, 215, 111, 244, 194, 89, 174, 53, 3, 152, 118, 237, 219, 64, 183, 44, 26, 129, 93, 198, 240, 107, 156, 7, 49, 170, 68, 223, 233, 114, 133, 30, 40, 179, 195, 88, 110, 245, 2, 153, 175, 52, 218, 65, 119, 236, 27, 128, 182, 45, 241, 106, 92, 199, 48, 171, 157, 6, 232, 115, 69, 222, 41, 178, 132, 31, 167, 60, 10, 145, 102, 253, 203, 80, 190, 37, 19, 136, 127, 228, 210, 73, 149, 14, 56, 163, 84, 207, 249, 98, 140, 23, 33, 186, 77, 214, 224, 123)
private val packages = mutableListOf<ByteArray>()
private var index = 0
private var sequenceNumber = 0
fun setData(inputData: ByteArray) {
resetPackets()
// PackageIndex: 0 initially, if there are multiple packet, for the first packet it is set to 0 (not included in crc calc but sent in actual header)
init {
// PackageIndex: 0 initially, if there are multiple packets, for the first packet it is set to 0 (not included in CRC calculation but sent in actual header)
var pkgIndex = 0
var header = byteArrayOf(
(inputData.size + 4).toByte(),
inputData[0],
(data.size + 4).toByte(),
data[0],
sequenceNumber.toByte(),
pkgIndex.toByte()
)
var tmp: ByteArray = header + inputData.copyOfRange(1, inputData.size)
var tmp: ByteArray = header + data.copyOfRange(1, data.size)
var totalCommand: ByteArray = tmp + calcCrc8(tmp, tmp.size).toByte()
if ((totalCommand.size - header.size) <= 15) {
@ -45,7 +43,6 @@ class WriteCommandPackets() {
tmp = header + remainingCommand
packages.add(tmp + calcCrc8(tmp, tmp.size).toByte())
}
sequenceNumber = (sequenceNumber % 255) + 1
}
fun getNextPacket(): ByteArray? {
@ -61,11 +58,6 @@ class WriteCommandPackets() {
return !(index < packages.size)
}
private fun resetPackets() {
packages.clear()
index = 0
}
private fun calcCrc8(value: ByteArray, size: Int): Int {
var crc8 = 0
for (i in 0 until size) {

View file

@ -96,7 +96,8 @@ class BLEComm @Inject internal constructor(
private var uartRead: BluetoothGattCharacteristic? = null
// Read and write buffers
private var mWritePackets = WriteCommandPackets()
private var mWritePackets: WriteCommandPackets? = null
private var mWriteSequenceNumber: Int = 0
private var mReadPacket: ReadDataPacket? = null
private var mDeviceSN: Long = 0
@ -157,9 +158,6 @@ class BLEComm @Inject internal constructor(
return false
}
// TODO: THIS IS A WORKAROUND TEST
mWritePackets = WriteCommandPackets()
if (mDevice != null && mDeviceSN == deviceSN) {
// Skip scanning and directly connect to gatt
aapsLogger.debug(LTag.PUMPBTCOMM, "Skipping scan and directly connecting to gatt")
@ -180,6 +178,8 @@ class BLEComm @Inject internal constructor(
@SuppressLint("MissingPermission")
@Synchronized
private fun connectGatt(device: BluetoothDevice) {
// Reset sequence counter
mWriteSequenceNumber = 0
mBluetoothGatt =
device.connectGatt(context, false, mGattCallback, BluetoothDevice.TRANSPORT_LE)
}
@ -280,10 +280,12 @@ class BLEComm @Inject internal constructor(
if (status == BluetoothGatt.GATT_SUCCESS) {
// Check if we need to finish our command!
synchronized(mWritePackets) {
val value: ByteArray? = mWritePackets.getNextPacket()
if (value != null) {
writeCharacteristic(uartWriteBTGattChar, value)
mWritePackets?.let {
synchronized(it) {
val value: ByteArray? = mWritePackets?.getNextPacket()
if (value != null) {
writeCharacteristic(uartWriteBTGattChar, value)
}
}
}
} else {
@ -397,21 +399,21 @@ class BLEComm @Inject internal constructor(
}
}
@Synchronized
fun sendMessage(message: ByteArray) {
aapsLogger.debug(LTag.PUMPBTCOMM, "sendMessage message = " + Arrays.toString(message))
if (!mWritePackets.allPacketsConsumed()) {
if (mWritePackets?.allPacketsConsumed() == false) {
aapsLogger.error(LTag.PUMPBTCOMM, "sendMessage not all packets consumed!! unable to sent message!")
return
}
synchronized(mWritePackets) {
mWritePackets.setData(message)
val value: ByteArray? = mWritePackets.getNextPacket()
if (value != null) {
writeCharacteristic(uartWriteBTGattChar, value)
} else {
aapsLogger.error(LTag.PUMPBTCOMM, "sendMessage error in writePacket!")
mCallback?.onSendMessageError("error in writePacket!")
}
mWritePackets = WriteCommandPackets(message, mWriteSequenceNumber)
mWriteSequenceNumber = (mWriteSequenceNumber + 1) % 256
val value: ByteArray? = mWritePackets?.getNextPacket()
if (value != null) {
writeCharacteristic(uartWriteBTGattChar, value)
} else {
aapsLogger.error(LTag.PUMPBTCOMM, "sendMessage error in writePacket!")
mCallback?.onSendMessageError("error in writePacket!")
}
}
@ -426,18 +428,6 @@ class BLEComm @Inject internal constructor(
return mBluetoothGatt?.getService(UUID.fromString(SERVICE_UUID))
}
private fun getGattCharacteristic(uuid: UUID): BluetoothGattCharacteristic? {
aapsLogger.debug(LTag.PUMPBTCOMM, "getGattCharacteristic $uuid")
val service = getGattService()
if (mBluetoothAdapter == null || mBluetoothGatt == null || service == null) {
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
isConnecting = false
isConnected = false
return null
}
return service.getCharacteristic(uuid)
}
@Suppress("DEPRECATION")
@SuppressLint("MissingPermission")
@Synchronized

View file

@ -123,7 +123,7 @@
android:gravity="center_horizontal"
android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text="@string/colon"
android:text=":"
android:textSize="16sp" />
<TextView

View file

@ -9,8 +9,8 @@ class WriteCommandPacketsTest {
fun Given14LongCommandExpectOnePacket() {
val input = byteArrayOf(5, 2, 0, 0, 0, 0, -21, 57, -122, -56)
val expect = byteArrayOf(14, 5, 0, 0, 2, 0, 0, 0, 0, -21, 57, -122, -56, -93, 0)
val cmdPackets = WriteCommandPackets()
cmdPackets.setData(input)
val sequence = 0
val cmdPackets = WriteCommandPackets(input, sequence)
val output = cmdPackets.getNextPacket()
assertEquals(expect.contentToString(), output.contentToString())
@ -23,8 +23,8 @@ class WriteCommandPacketsTest {
val expect2 = byteArrayOf(41, 18, 0, 2, 0, -96, 2, -16, 96, 2, 104, 33, 2, -32, -31, 1, -64, 3, 2, -3)
val expect3 = byteArrayOf(41, 18, 0, 3, -20, 36, 2, 100, -123, 2, -125, -89)
val cmdPackets = WriteCommandPackets()
cmdPackets.setData(input)
val sequence = 0
val cmdPackets = WriteCommandPackets(input, sequence)
val output1 = cmdPackets.getNextPacket()
val output2 = cmdPackets.getNextPacket()
val output3 = cmdPackets.getNextPacket()
@ -37,56 +37,4 @@ class WriteCommandPacketsTest {
assertNull(output4)
assertEquals(true, cmdPackets.allPacketsConsumed())
}
@Test
fun Given2CommandsExpectWriteIndexInHeaderIncrease() {
val input1 = byteArrayOf(66)
val input2 = byteArrayOf(99)
val expect1 = byteArrayOf(5, 66, 0, 0, -25, 0)
val expect2 = byteArrayOf(5, 99, 1, 0, 64, 0)
val cmdPackets = WriteCommandPackets()
cmdPackets.setData(input1)
val output1 = cmdPackets.getNextPacket()
cmdPackets.setData(input2)
val output2 = cmdPackets.getNextPacket()
assertEquals(expect1.contentToString(), output1.contentToString())
assertEquals(expect2.contentToString(), output2.contentToString())
}
@Test
fun GivenSequenceNumberOverflowExpectSequenceNumber1() {
val input1 = byteArrayOf(55)
val input2 = byteArrayOf(66)
val input3 = byteArrayOf(99)
val expect1 = byteArrayOf(5, 55, -2, 0, -19, 0)
val expect2 = byteArrayOf(5, 66, -1, 0, 86, 0)
val expect3 = byteArrayOf(5, 99, 1, 0, 64, 0)
val cmdPackets = WriteCommandPackets()
// All this stuff to set the private field ^^
val sequenceNumber = WriteCommandPackets::class.java.getDeclaredField("sequenceNumber")
sequenceNumber.isAccessible = true
sequenceNumber.setInt(cmdPackets, 254)
cmdPackets.setData(input1)
val output1 = cmdPackets.getNextPacket()
cmdPackets.setData(input2)
val output2 = cmdPackets.getNextPacket()
cmdPackets.setData(input3)
val output3 = cmdPackets.getNextPacket()
assertEquals(expect1.contentToString(), output1.contentToString())
assertEquals(expect2.contentToString(), output2.contentToString())
assertEquals(expect3.contentToString(), output3.contentToString())
}
}