feat: add version read, OTA characteristic, BLE MTU 512 in BleRelayManager
This commit is contained in:
parent
6042eceeea
commit
5235057b83
1 changed files with 48 additions and 3 deletions
|
|
@ -23,23 +23,27 @@ import java.nio.ByteOrder
|
|||
import java.util.UUID
|
||||
import javax.crypto.Mac
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
import kotlin.text.Charsets
|
||||
|
||||
class BleRelayManager(
|
||||
private val context: Context,
|
||||
private val callbacks: BleCallbacks
|
||||
) {
|
||||
companion object {
|
||||
var instance: BleRelayManager? = null
|
||||
private const val TAG = "BleRelayManager"
|
||||
private val SERVICE_UUID: UUID = UUID.fromString("4fafc201-1fb5-459e-8fcc-c5c9c331914b")
|
||||
private val CHARACTERISTIC_UUID: UUID = UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361f26d8")
|
||||
private val UUID_CHAR_UUID: UUID = UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361f26d9")
|
||||
private val VERSION_UUID: UUID = UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361f26db")
|
||||
private val OTA_UUID: UUID = UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361f26da")
|
||||
|
||||
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 const val BLE_MTU = 256
|
||||
private const val BLE_MTU = 512
|
||||
}
|
||||
|
||||
private var bluetoothGatt: BluetoothGatt? = null
|
||||
|
|
@ -52,6 +56,13 @@ class BleRelayManager(
|
|||
private var hmacKey: ByteArray? = null
|
||||
private var deviceUuid: ByteArray? = null
|
||||
private var triedAddresses = mutableSetOf<String>()
|
||||
private var otaCharacteristic: BluetoothGattCharacteristic? = null
|
||||
private var espVersion: String? = null
|
||||
private var appVersion: String = ""
|
||||
|
||||
init {
|
||||
instance = this
|
||||
}
|
||||
private val scanRunnable = Runnable { startScan() }
|
||||
private var scanTimeoutRunnable: Runnable? = null
|
||||
|
||||
|
|
@ -170,6 +181,22 @@ class BleRelayManager(
|
|||
stopScan()
|
||||
bluetoothGatt?.disconnect()
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
fun sendOtaData(data: ByteArray) {
|
||||
val char = otaCharacteristic ?: return
|
||||
val gatt = bluetoothGatt ?: return
|
||||
char.value = data
|
||||
char.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
|
||||
gatt.writeCharacteristic(char)
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
fun enableOtaNotifications(): Boolean {
|
||||
val char = otaCharacteristic ?: return false
|
||||
val gatt = bluetoothGatt ?: return false
|
||||
return gatt.setCharacteristicNotification(char, true)
|
||||
}
|
||||
fun updateKeys() {
|
||||
loadState()
|
||||
}
|
||||
|
|
@ -182,6 +209,10 @@ class BleRelayManager(
|
|||
return bluetoothGatt != null
|
||||
}
|
||||
|
||||
fun setAppVersion(version: String) {
|
||||
appVersion = version
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun connectToDevice(device: android.bluetooth.BluetoothDevice) {
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.Connecting) }
|
||||
|
|
@ -230,7 +261,9 @@ class BleRelayManager(
|
|||
val service = gatt.getService(SERVICE_UUID)
|
||||
if (service != null) {
|
||||
relayCharacteristic = service.getCharacteristic(CHARACTERISTIC_UUID)
|
||||
otaCharacteristic = service.getCharacteristic(OTA_UUID)
|
||||
val uuidChar = service.getCharacteristic(UUID_CHAR_UUID)
|
||||
val versionChar = service.getCharacteristic(VERSION_UUID)
|
||||
if (relayCharacteristic != null && uuidChar != null) {
|
||||
Log.d(TAG, "Reading device UUID characteristic...")
|
||||
gatt.readCharacteristic(uuidChar)
|
||||
|
|
@ -249,14 +282,26 @@ class BleRelayManager(
|
|||
if (characteristic.uuid == UUID_CHAR_UUID && status == BluetoothGatt.GATT_SUCCESS) {
|
||||
val storedUuid = deviceUuid
|
||||
if (storedUuid != null && value.contentEquals(storedUuid)) {
|
||||
Log.d(TAG, "UUID verified, setting up relay")
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.Connected) }
|
||||
Log.d(TAG, "UUID verified, reading version...")
|
||||
val service = gatt.getService(SERVICE_UUID)
|
||||
val versionChar = service?.getCharacteristic(VERSION_UUID)
|
||||
if (versionChar != null) {
|
||||
gatt.readCharacteristic(versionChar)
|
||||
} else {
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.Connected) }
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "UUID mismatch -- disconnecting")
|
||||
triedAddresses.add(gatt.device.address)
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.WrongDevice) }
|
||||
gatt.disconnect()
|
||||
}
|
||||
} else if (characteristic.uuid == VERSION_UUID && status == BluetoothGatt.GATT_SUCCESS) {
|
||||
val version = String(value, Charsets.UTF_8).trim()
|
||||
espVersion = version
|
||||
Log.d(TAG, "ESP firmware version: $version, app bundled: $appVersion")
|
||||
handler.post { callbacks.onFirmwareVersion(version, appVersion) }
|
||||
handler.post { callbacks.onStatusChanged(BleStatus.Connected) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue