WIP: sp1sp2
This commit is contained in:
parent
4e6ad3f113
commit
318c0c642c
|
@ -95,7 +95,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(private val context: Context
|
|||
companion object {
|
||||
|
||||
private const val CONNECT_TIMEOUT_MS = 5000
|
||||
private const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else.
|
||||
public const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else.
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +1,65 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ltk
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.Address
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManagerImpl
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.Id
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType
|
||||
import info.nightscout.androidaps.utils.extensions.hexStringToByteArray
|
||||
import info.nightscout.androidaps.utils.extensions.toHex
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
internal class LTKExchanger(private val aapsLogger: AAPSLogger,private val msgIO: MessageIO) {
|
||||
internal class LTKExchanger(private val aapsLogger: AAPSLogger, private val msgIO: MessageIO) {
|
||||
|
||||
fun negociateLTKAndNonce(): LTK? {
|
||||
// send SP1, SP2
|
||||
// TODO: get this from somewhere(preferences?)
|
||||
var seq: Byte = 1
|
||||
val controllerId = Id.fromInt(OmnipodDashBleManagerImpl.CONTROLLER_ID)
|
||||
val nodeId = controllerId.increment()
|
||||
|
||||
var sp1sp2 = sp1sp2(nodeId.address, sp2(), seq, controllerId, nodeId)
|
||||
msgIO.sendMesssage(sp1sp2.messagePacket)
|
||||
/*
|
||||
var sps1 =
|
||||
msgIO.sendMesssage(sps1.messagePacket)
|
||||
// send SPS1
|
||||
// read SPS1
|
||||
val podSps1 = msgIO.receiveMessage()
|
||||
|
||||
// send SPS2
|
||||
var sps2 = PairMessage()
|
||||
msgIO.sendMesssage(sps2.messagePacket)
|
||||
// read SPS2
|
||||
val podSps2 = msgIO.receiveMessage()
|
||||
|
||||
// send SP0GP0
|
||||
msgIO.sendMesssage(sps2.messagePacket)
|
||||
// read P0
|
||||
|
||||
val msg = MessagePacket(
|
||||
destination = Address(byteArrayOf(1,2,3,4)),
|
||||
source = Address(byteArrayOf(5,6,7,8)),
|
||||
payload = "545710030100038002420000fffffffe5350313d0004024200032c5350323d000bffc32dbd20030e01000016".hexStringToByteArray(),
|
||||
sequenceNumber = 1,
|
||||
type = MessageType.PAIRING,
|
||||
)
|
||||
msgIO.sendMesssage(msg)
|
||||
|
||||
val p0 = msgIO.receiveMessage()
|
||||
*/
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
private fun sp2(): ByteArray {
|
||||
// This is GetPodStatus command, with page 0 parameter.
|
||||
// We could replace that in the future with the serialized GetPodStatus()
|
||||
return GET_POD_STATUS_HEX_COMMAND.hexStringToByteArray()
|
||||
}
|
||||
|
||||
fun sp1sp2(sp1: ByteArray, sp2: ByteArray, seq: Byte, controllerId: Id, nodeId: Id): PairMessage {
|
||||
val payload = "SP1=".toByteArray() + sp1
|
||||
",SP2=".toByteArray() + sp2
|
||||
return PairMessage(
|
||||
sequenceNumber = seq,
|
||||
source = controllerId,
|
||||
destination = nodeId,
|
||||
payload = payload,
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val GET_POD_STATUS_HEX_COMMAND = "ffc32dbd08030e0100008a" // TODO for now we are assuming this command is build out of constant parameters, use a proper command builder for that.
|
||||
}
|
||||
}
|
|
@ -1,3 +1,21 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ltk
|
||||
|
||||
class PairMessage
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.Id
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType
|
||||
|
||||
data class PairMessage(
|
||||
val sequenceNumber: Byte,
|
||||
val source: Id,
|
||||
val destination: Id,
|
||||
val payload: ByteArray,
|
||||
val messagePacket: MessagePacket = MessagePacket(
|
||||
type=MessageType.PAIRING,
|
||||
source=source,
|
||||
destination = destination,
|
||||
encryptedPayload=false,
|
||||
payload=payload,
|
||||
sequenceNumber=sequenceNumber,
|
||||
sas=true, // TODO: understand why this is true for PairMessages
|
||||
),
|
||||
) {}
|
|
@ -1,7 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||
|
||||
data class Address(val address: ByteArray) {
|
||||
init {
|
||||
require(address.size == 4)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ltk.LTKExchanger
|
||||
import info.nightscout.androidaps.utils.extensions.toHex
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
data class Id(val address: ByteArray) {
|
||||
init {
|
||||
require(address.size == 4)
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to obtain podId from controllerId
|
||||
*/
|
||||
fun increment(): Id {
|
||||
val nodeId = address.copyOf()
|
||||
nodeId[3] = (nodeId[3].toInt() and -4).toByte()
|
||||
nodeId[3] = (nodeId[3].toInt() or PERIPHERAL_NODE_INDEX).toByte()
|
||||
return Id(nodeId)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val asInt = ByteBuffer.wrap(address).getInt()
|
||||
return "${asInt}/${address.toHex()}"
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val PERIPHERAL_NODE_INDEX = 1 // TODO: understand the meaning of this value. It comes from preferences
|
||||
|
||||
fun fromInt(v: Int): Id {
|
||||
return Id(ByteBuffer.allocate(4).putInt(v).array())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||
|
||||
interface Message {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
fun messagePacket(): MessagePacket
|
||||
}
|
|
@ -1,9 +1,38 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||
|
||||
import java.io.DataOutput
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
/***
|
||||
* MessagePacket contains header and raw payload for a message
|
||||
*/
|
||||
|
||||
class Flag:Byte{
|
||||
fun set(idx: Byte, val: Boolean) {
|
||||
val mask = 1 <lsh (7-idx)
|
||||
|
||||
}
|
||||
func (f *flag) set(index byte, val bool) {
|
||||
var mask flag = 1 << (7 - index)
|
||||
if !val {
|
||||
return
|
||||
}
|
||||
*f |= mask
|
||||
}
|
||||
|
||||
func (f flag) get(index byte) byte {
|
||||
var mask flag = 1 << (7 - index)
|
||||
if f&mask == 0 {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
data class MessagePacket(
|
||||
val type: MessageType,
|
||||
val source: Address,
|
||||
val destination: Address,
|
||||
val source: Id,
|
||||
val destination: Id,
|
||||
val payload: ByteArray,
|
||||
val sequenceNumber: Byte,
|
||||
val ack: Boolean = false,
|
||||
|
@ -17,11 +46,17 @@ data class MessagePacket(
|
|||
val version: Short = 0.toShort()) {
|
||||
|
||||
fun asByteArray(): ByteArray {
|
||||
// TODO: implement proper serialization
|
||||
val v = ByteBuffer.allocate(16+ payload.size)
|
||||
v.put(MAGIC_PATTERN.toByteArray())
|
||||
val f1: Byte=0
|
||||
|
||||
|
||||
return this.payload
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val MAGIC_PATTERN = "TW" // all messages start with this string
|
||||
|
||||
fun parse(payload: ByteArray): MessagePacket {
|
||||
TODO("implement message header parsing")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||
|
||||
/***
|
||||
* String prefix and length encoding and decoding. Example message:
|
||||
*/
|
||||
class StringLengthPrefixEncoding {
|
||||
|
||||
companion object {
|
||||
fun parseKeys(keys: List<String>): List<ByteArray> {
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
fun formatKeys(keys: List<String>, payload: List<ByteArray>, addLength: Boolean): ByteArray {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue