From 223f6746b0eb7fd48128a7428647954877822bb5 Mon Sep 17 00:00:00 2001 From: crc-32 Date: Mon, 24 Apr 2023 02:17:42 +0100 Subject: [PATCH] functional fw updates --- gradle.properties | 5 +++-- .../rebble/libpebblecommon/ProtocolHandlerImpl.kt | 1 - .../metadata/pbz/manifest/PbzManifest.kt | 2 +- .../io/rebble/libpebblecommon/packets/PutBytes.kt | 7 ++----- .../io/rebble/libpebblecommon/packets/System.kt | 11 ++++++++--- .../protocolhelpers/ProtocolEndpoint.kt | 1 + .../libpebblecommon/services/PutBytesService.kt | 15 +++++++++------ .../libpebblecommon/services/SystemService.kt | 12 ++++++++---- 8 files changed, 32 insertions(+), 22 deletions(-) diff --git a/gradle.properties b/gradle.properties index 996bb57..6ec2886 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,10 @@ kotlin.code.style=official group=io.rebble.libpebblecommon -version=0.1.11 +version=0.1.12 org.gradle.jvmargs=-Xms128M -Xmx1G -XX:ReservedCodeCacheSize=200M kotlin.native.binary.memoryModel=experimental kotlin.mpp.androidSourceSetLayoutVersion=2 kotlinVersion=1.8.10 -agpVersion=7.4.0 \ No newline at end of file +agpVersion=7.4.0 +android.disableAutomaticComponentCreation=true \ No newline at end of file diff --git a/src/commonMain/kotlin/io/rebble/libpebblecommon/ProtocolHandlerImpl.kt b/src/commonMain/kotlin/io/rebble/libpebblecommon/ProtocolHandlerImpl.kt index 5657f6b..f91be63 100644 --- a/src/commonMain/kotlin/io/rebble/libpebblecommon/ProtocolHandlerImpl.kt +++ b/src/commonMain/kotlin/io/rebble/libpebblecommon/ProtocolHandlerImpl.kt @@ -158,5 +158,4 @@ class ProtocolHandlerImpl() : ProtocolHandler { } return true } - } diff --git a/src/commonMain/kotlin/io/rebble/libpebblecommon/metadata/pbz/manifest/PbzManifest.kt b/src/commonMain/kotlin/io/rebble/libpebblecommon/metadata/pbz/manifest/PbzManifest.kt index a890420..20ae9f4 100644 --- a/src/commonMain/kotlin/io/rebble/libpebblecommon/metadata/pbz/manifest/PbzManifest.kt +++ b/src/commonMain/kotlin/io/rebble/libpebblecommon/metadata/pbz/manifest/PbzManifest.kt @@ -11,7 +11,7 @@ data class PbzManifest( val generatedBy: String, val debug: Debug, val firmware: PbzFirmware, - val resources: SystemResources, + val resources: SystemResources?, @SerialName("js_tooling") val jsTooling: JsTooling, val type: String diff --git a/src/commonMain/kotlin/io/rebble/libpebblecommon/packets/PutBytes.kt b/src/commonMain/kotlin/io/rebble/libpebblecommon/packets/PutBytes.kt index 24cc3a9..ac46b4c 100644 --- a/src/commonMain/kotlin/io/rebble/libpebblecommon/packets/PutBytes.kt +++ b/src/commonMain/kotlin/io/rebble/libpebblecommon/packets/PutBytes.kt @@ -3,10 +3,7 @@ package io.rebble.libpebblecommon.packets import io.rebble.libpebblecommon.protocolhelpers.PacketRegistry import io.rebble.libpebblecommon.protocolhelpers.PebblePacket import io.rebble.libpebblecommon.protocolhelpers.ProtocolEndpoint -import io.rebble.libpebblecommon.structmapper.SBytes -import io.rebble.libpebblecommon.structmapper.SNullTerminatedString -import io.rebble.libpebblecommon.structmapper.SUByte -import io.rebble.libpebblecommon.structmapper.SUInt +import io.rebble.libpebblecommon.structmapper.* sealed class PutBytesOutgoingPacket(command: PutBytesCommand) : PebblePacket(ProtocolEndpoint.PUT_BYTES) { @@ -42,7 +39,7 @@ class PutBytesInit( val objectSize = SUInt(m, objectSize) val objectType = SUByte(m, objectType.value) val bank = SUByte(m, bank) - val filename = SNullTerminatedString(m, filename) + val filename = SOptional(m, SNullTerminatedString(StructMapper(), filename), filename.isNotEmpty()) } /** diff --git a/src/commonMain/kotlin/io/rebble/libpebblecommon/packets/System.kt b/src/commonMain/kotlin/io/rebble/libpebblecommon/packets/System.kt index 8138a1c..3ae2816 100644 --- a/src/commonMain/kotlin/io/rebble/libpebblecommon/packets/System.kt +++ b/src/commonMain/kotlin/io/rebble/libpebblecommon/packets/System.kt @@ -397,10 +397,11 @@ open class SystemMessage(message: Message) : SystemPacket(endpoint) { FirmwareUpdateStartResponse(0x0au) } - val command = SUByte(m, message.value) + val command = SUByte(m, 0x0u) + val messageType = SUByte(m, message.value) init { - type = command.get() + type = messageType.get() } companion object { @@ -408,7 +409,10 @@ open class SystemMessage(message: Message) : SystemPacket(endpoint) { } class NewFirmwareAvailable: SystemMessage(Message.NewFirmwareAvailable) - class FirmwareUpdateStart: SystemMessage(Message.FirmwareUpdateStart) + class FirmwareUpdateStart(bytesAlreadyTransferred: UInt, bytesToSend: UInt): SystemMessage(Message.FirmwareUpdateStart) { + val bytesAlreadyTransferred = SUInt(m, bytesAlreadyTransferred, endianness = '<') + val bytesToSend = SUInt(m, bytesToSend, endianness = '<') + } class FirmwareUpdateComplete: SystemMessage(Message.FirmwareUpdateComplete) class FirmwareUpdateFailed: SystemMessage(Message.FirmwareUpdateFailed) class FirmwareUpToDate: SystemMessage(Message.FirmwareUpToDate) @@ -504,6 +508,7 @@ fun systemPacketsRegister() { PacketRegistry.register(PingPong.endpoint, PingPong.Message.Ping.value) { PingPong.Ping() } PacketRegistry.register(PingPong.endpoint, PingPong.Message.Pong.value) { PingPong.Pong() } + PacketRegistry.registerCustomTypeOffset(SystemMessage.endpoint, 5) // command is always 0, type is next byte PacketRegistry.register( SystemMessage.endpoint, SystemMessage.Message.FirmwareUpdateStartResponse.value diff --git a/src/commonMain/kotlin/io/rebble/libpebblecommon/protocolhelpers/ProtocolEndpoint.kt b/src/commonMain/kotlin/io/rebble/libpebblecommon/protocolhelpers/ProtocolEndpoint.kt index c56c55e..4e7b7ce 100644 --- a/src/commonMain/kotlin/io/rebble/libpebblecommon/protocolhelpers/ProtocolEndpoint.kt +++ b/src/commonMain/kotlin/io/rebble/libpebblecommon/protocolhelpers/ProtocolEndpoint.kt @@ -3,6 +3,7 @@ package io.rebble.libpebblecommon.protocolhelpers import co.touchlab.kermit.Logger enum class ProtocolEndpoint(val value: UShort) { + RECOVERY(0u), TIME(11u), WATCH_VERSION(16u), PHONE_VERSION(17u), diff --git a/src/commonMain/kotlin/io/rebble/libpebblecommon/services/PutBytesService.kt b/src/commonMain/kotlin/io/rebble/libpebblecommon/services/PutBytesService.kt index 3f6c3aa..6882960 100644 --- a/src/commonMain/kotlin/io/rebble/libpebblecommon/services/PutBytesService.kt +++ b/src/commonMain/kotlin/io/rebble/libpebblecommon/services/PutBytesService.kt @@ -12,6 +12,7 @@ import io.rebble.libpebblecommon.util.DataBuffer import io.rebble.libpebblecommon.util.getPutBytesMaximumDataSize import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.withTimeout +import kotlin.math.log class PutBytesService(private val protocolHandler: ProtocolHandler) : ProtocolService { val receivedMessages = Channel(Channel.BUFFERED) @@ -22,6 +23,7 @@ class PutBytesService(private val protocolHandler: ProtocolHandler) : ProtocolSe data class PutBytesProgress( val count: Int, val total: Int, + val delta: Int, val cookie: UInt ) @@ -87,14 +89,15 @@ class PutBytesService(private val protocolHandler: ProtocolHandler) : ProtocolSe watchVersion: WatchVersion.WatchVersionResponse, crc: Long, size: UInt, - type: ObjectType, - fileName: String + bank: UByte, + type: ObjectType ) { logger.i { "Send FW part $type ${type.value}" } send( - PutBytesInit(size, type, 0u, fileName) + PutBytesInit(size, type, bank, "") ) + logger.d { "Putting byte array" } val cookie = awaitCookieAndPutByteArray( blob, crc, @@ -121,10 +124,10 @@ class PutBytesService(private val protocolHandler: ProtocolHandler) : ProtocolSe val cookie = awaitAck().cookie.get() lastCookie = cookie progressUpdates.trySend( - PutBytesProgress(0, totalToPut, cookie) + PutBytesProgress(0, totalToPut, 0, cookie) ) - val maxDataSize = getPutBytesMaximumDataSize(watchVersion) + val maxDataSize = if (watchVersion.running.isRecovery.get()) 2000 else getPutBytesMaximumDataSize(watchVersion) val buffer = DataBuffer(byteArray.asUByteArray()) val crcCalculator = Crc32Calculator() @@ -142,7 +145,7 @@ class PutBytesService(private val protocolHandler: ProtocolHandler) : ProtocolSe awaitAck() totalBytes += dataToRead progressUpdates.trySend( - PutBytesProgress(totalBytes, totalToPut, cookie) + PutBytesProgress(totalBytes, totalToPut, dataToRead, cookie) ) } val calculatedCrc = crcCalculator.finalize() diff --git a/src/commonMain/kotlin/io/rebble/libpebblecommon/services/SystemService.kt b/src/commonMain/kotlin/io/rebble/libpebblecommon/services/SystemService.kt index 68b43de..ef34530 100644 --- a/src/commonMain/kotlin/io/rebble/libpebblecommon/services/SystemService.kt +++ b/src/commonMain/kotlin/io/rebble/libpebblecommon/services/SystemService.kt @@ -1,5 +1,6 @@ package io.rebble.libpebblecommon.services +import co.touchlab.kermit.Logger import io.rebble.libpebblecommon.PacketPriority import io.rebble.libpebblecommon.ProtocolHandler import io.rebble.libpebblecommon.packets.* @@ -26,6 +27,7 @@ class SystemService(private val protocolHandler: ProtocolHandler) : ProtocolServ protocolHandler.registerReceiveCallback(ProtocolEndpoint.PHONE_VERSION, this::receive) protocolHandler.registerReceiveCallback(ProtocolEndpoint.WATCH_VERSION, this::receive) protocolHandler.registerReceiveCallback(ProtocolEndpoint.FCT_REG, this::receive) + protocolHandler.registerReceiveCallback(ProtocolEndpoint.SYSTEM_MESSAGE, this::receive) } /** @@ -55,13 +57,11 @@ class SystemService(private val protocolHandler: ProtocolHandler) : ProtocolServ return SInt(StructMapper()).also { it.fromBytes(DataBuffer(modelBytes)) }.get() } - suspend fun firmwareUpdateStart(): UByte { + suspend fun firmwareUpdateStart(bytesAlreadyTransferred: UInt, bytesToSend: UInt): UByte { val callback = CompletableDeferred() firmwareUpdateStartResponseCallback = callback - send(SystemMessage.FirmwareUpdateStart()) - + send(SystemMessage.FirmwareUpdateStart(bytesAlreadyTransferred, bytesToSend)) val response = callback.await() - return response.response.get() } @@ -89,6 +89,10 @@ class SystemService(private val protocolHandler: ProtocolHandler) : ProtocolServ send(res) // Cannot be low priority } } + is SystemMessage.FirmwareUpdateStartResponse -> { + firmwareUpdateStartResponseCallback?.complete(packet) + firmwareUpdateStartResponseCallback = null + } else -> receivedMessages.trySend(packet) } }