feat: add BleRelayManager key/HMAC helpers and loadState

This commit is contained in:
eddy 2026-07-29 19:49:00 +02:00
commit 82852e086e

View file

@ -7,6 +7,10 @@ import android.content.Context
import android.os.Handler
import android.os.Looper
import java.util.UUID
import java.nio.ByteBuffer
import java.nio.ByteOrder
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
class BleRelayManager(
private val context: Context,
@ -20,6 +24,8 @@ class BleRelayManager(
private const val SCAN_TIMEOUT_MS = 30000L
private const val RECONNECT_DELAY_MS = 2000L
private const val MAX_SCAN_RETRIES = 3
private const val HMAC_PKT_SIZE = 37
private const val HMAC_LEN = 32
}
private var bluetoothGatt: BluetoothGatt? = null
@ -37,9 +43,52 @@ class BleRelayManager(
fun stopScan() {}
fun sendRelayCommand(cmd: Byte) {}
fun disconnect() {}
fun updateKeys() {}
fun resetTriedAddresses() {}
fun updateKeys() {
loadState()
}
fun resetTriedAddresses() {
triedAddresses.clear()
}
fun hasPermissions(): Boolean = false
fun getRequiredPermissions(): Array<String> = emptyArray()
fun destroy() {}
fun destroy() {
handler.removeCallbacksAndMessages(null)
}
private fun loadState() {
val prefs = PrefsHelper.getPrefs(context)
val hexKey = prefs.getString(PrefsHelper.PREF_KEY, null)
hmacKey = hexKey?.let { hexStringToBytes(it) }
val hexUuid = prefs.getString(PrefsHelper.PREF_UUID, null)
deviceUuid = hexUuid?.let { hexStringToBytes(it) }
seq = prefs.getInt(PrefsHelper.PREF_SEQ, 1).coerceAtMost(PrefsHelper.SEQ_MAX)
}
private fun hexStringToBytes(hex: String): ByteArray? {
val cleaned = hex.uppercase().filter { it in "0123456789ABCDEF" }
if (cleaned.isEmpty() || cleaned.length % 2 != 0) return null
return cleaned.chunked(2).map { it.toInt(16).toByte() }.toByteArray()
}
private fun hmacSha256(data: ByteArray, key: ByteArray): ByteArray {
val mac = Mac.getInstance("HmacSHA256")
mac.init(SecretKeySpec(key, "HmacSHA256"))
return mac.doFinal(data)
}
private fun buildPacket(cmd: Byte, key: ByteArray): ByteArray {
val seqBytes = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(seq).array()
val hmacData = ByteArray(5)
hmacData[0] = cmd
System.arraycopy(seqBytes, 0, hmacData, 1, 4)
val hmac = hmacSha256(hmacData, key)
val packet = ByteArray(HMAC_PKT_SIZE)
packet[0] = cmd
System.arraycopy(seqBytes, 0, packet, 1, 4)
System.arraycopy(hmac, 0, packet, 5, HMAC_LEN)
return packet
}
}