This commit is contained in:
Andrei Vereha 2021-04-04 13:32:09 +02:00
parent 64fbea6afe
commit ff6a67cc97
4 changed files with 91 additions and 63 deletions

View file

@ -137,6 +137,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(
private fun establishSession(msgSeq: Byte) {
val conn = connection ?: throw FailedToConnectException("connection lost")
val ltk: ByteArray = podState.ltk ?: throw FailedToConnectException("Missing LTK, activate the pod first")
val uniqueId = podState.uniqueId
val podId = uniqueId?.let { Id.fromLong(uniqueId) }
?: myId.increment() // pod not activated

View file

@ -97,20 +97,18 @@ open class BleIO(
* @return
*/
fun readyToRead(): BleSendResult {
val notificationSet = gatt.setCharacteristicNotification(characteristic, true)
if (!notificationSet) {
throw ConnectException("Could not enable notifications")
}
gatt.setCharacteristicNotification(characteristic, true)
.assertTrue("enable notifications")
val descriptors = characteristic.descriptors
if (descriptors.size != 1) {
throw ConnectException("Expecting one descriptor, found: ${descriptors.size}")
}
val descriptor = descriptors[0]
descriptor.value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
val wrote = gatt.writeDescriptor(descriptor)
if (!wrote) {
throw ConnectException("Could not enable indications on descriptor")
}
gatt.writeDescriptor(descriptor)
.assertTrue("enable indications on descriptor")
aapsLogger.debug(LTag.PUMPBTCOMM, "Enabling indications for $type")
val confirmation = bleCommCallbacks.confirmWrite(
BluetoothGattDescriptor.ENABLE_INDICATION_VALUE,
@ -130,3 +128,9 @@ open class BleIO(
const val DEFAULT_IO_TIMEOUT_MS = 1000.toLong()
}
}
private fun Boolean.assertTrue(operation: String) {
if (!this) {
throw ConnectException("Could not $operation")
}
}

View file

@ -62,13 +62,11 @@ data class EapMessage(
private const val AKA_PACKET_TYPE = 0x17.toByte()
fun parse(aapsLogger: AAPSLogger, payload: ByteArray): EapMessage {
if (payload.size < 4) {
throw MessageIOException("Invalid eap payload: ${payload.toHex()}")
}
payload.assertSizeAtLeast(4)
val totalSize = (payload[2].toInt() shl 8) or payload[3].toInt()
if (totalSize > payload.size) {
throw MessageIOException("Invalid eap payload. Too short: ${payload.toHex()}")
}
payload.assertSizeAtLeast(totalSize)
if (payload.size == 4) { // SUCCESS/FAILURE
return EapMessage(
code = EapCode.byValue(payload[0]),
@ -90,3 +88,9 @@ data class EapMessage(
}
}
}
private fun ByteArray.assertSizeAtLeast(size: Int) {
if (this.size < size) {
throw MessageIOException("Payload too short: ${this.toHex()}")
}
}

View file

@ -90,20 +90,65 @@ class SessionEstablisher(
)
}
private fun processChallengeResponse(challengeResponse: MessagePacket): EapSqn? {
val eapMsg = EapMessage.parse(aapsLogger, challengeResponse.payload)
if (eapMsg.identifier != identifier) {
private fun assertIdentifier(msg: EapMessage) {
if (msg.identifier != identifier) {
aapsLogger.debug(
LTag.PUMPBTCOMM,
"EAP-AKA: got incorrect identifier ${eapMsg.identifier} expected: $identifier"
"EAP-AKA: got incorrect identifier ${msg.identifier} expected: $identifier"
)
throw SessionEstablishmentException("Received incorrect EAP identifier: ${eapMsg.identifier}")
throw SessionEstablishmentException("Received incorrect EAP identifier: ${msg.identifier}")
}
}
if (eapMsg.subType == EapMessage.SUBTYPE_SYNCRONIZATION_FAILURE &&
eapMsg.attributes.size == 1 &&
eapMsg.attributes[0] is EapAkaAttributeAuts
) {
private fun processChallengeResponse(challengeResponse: MessagePacket): EapSqn? {
val eapMsg = EapMessage.parse(aapsLogger, challengeResponse.payload)
assertIdentifier(eapMsg)
val eapSqn = isResynchronization(eapMsg)
if (eapSqn != null) {
return eapSqn
}
assertValidAkaMessage(eapMsg)
for (attr in eapMsg.attributes) {
when (attr) {
is EapAkaAttributeRes ->
if (!milenage.res.contentEquals(attr.payload)) {
throw SessionEstablishmentException("RES mismatch." +
"Expected: ${milenage.res.toHex()}." +
"Actual: ${attr.payload.toHex()}.")
}
is EapAkaAttributeCustomIV ->
nodeIV = attr.payload.copyOfRange(0, IV_SIZE)
else ->
throw SessionEstablishmentException("Unknown attribute received: $attr")
}
}
return null
}
private fun assertValidAkaMessage(eapMsg: EapMessage) {
if (eapMsg.attributes.size != 2) {
aapsLogger.debug(LTag.PUMPBTCOMM, "EAP-AKA: got incorrect: $eapMsg")
if (eapMsg.attributes.size == 1 && eapMsg.attributes[0] is EapAkaAttributeClientErrorCode) {
throw SessionEstablishmentException(
"Received CLIENT_ERROR_CODE for EAP-AKA challenge: ${
eapMsg.attributes[0].toByteArray().toHex()
}"
)
}
throw SessionEstablishmentException("Expecting two attributes, got: ${eapMsg.attributes.size}")
}
}
private fun isResynchronization(eapMsg: EapMessage): EapSqn? {
if (eapMsg.subType != EapMessage.SUBTYPE_SYNCRONIZATION_FAILURE ||
eapMsg.attributes.size != 1 ||
eapMsg.attributes[0] !is EapAkaAttributeAuts)
return null
val auts = eapMsg.attributes[0] as EapAkaAttributeAuts
val autsMilenage = Milenage(
aapsLogger = aapsLogger,
@ -130,33 +175,7 @@ class SessionEstablisher(
)
}
return EapSqn(autsMilenage.synchronizationSqn)
}
if (eapMsg.attributes.size != 2) {
aapsLogger.debug(LTag.PUMPBTCOMM, "EAP-AKA: got message: $eapMsg")
if (eapMsg.attributes.size == 1 && eapMsg.attributes[0] is EapAkaAttributeClientErrorCode) {
throw SessionEstablishmentException(
"Received CLIENT_ERROR_CODE for EAP-AKA challenge: ${
eapMsg.attributes[0].toByteArray().toHex()
}"
)
}
throw SessionEstablishmentException("Expecting two attributes, got: ${eapMsg.attributes.size}")
}
for (attr in eapMsg.attributes) {
when (attr) {
is EapAkaAttributeRes ->
if (!milenage.res.contentEquals(attr.payload)) {
throw SessionEstablishmentException("RES mismatch. Expected: ${milenage.res.toHex()} Actual: ${attr.payload.toHex()} ")
}
is EapAkaAttributeCustomIV ->
nodeIV = attr.payload.copyOfRange(0, IV_SIZE)
else ->
throw SessionEstablishmentException("Unknown attribute received: $attr")
}
}
return null
}
private fun eapSuccess(): MessagePacket {