diff --git a/bbootimg/src/main/kotlin/miscimg/MiscImage.kt b/bbootimg/src/main/kotlin/miscimg/MiscImage.kt index 4e4597e..41a4b61 100644 --- a/bbootimg/src/main/kotlin/miscimg/MiscImage.kt +++ b/bbootimg/src/main/kotlin/miscimg/MiscImage.kt @@ -3,10 +3,13 @@ package miscimg import cc.cfig.io.Struct import cfig.helper.Helper import org.slf4j.LoggerFactory +import java.io.ByteArrayInputStream import java.io.FileInputStream +import java.io.InputStream data class MiscImage( var bcb: BootloaderMessage = BootloaderMessage(), + var mbcb: MiscBootControl? = null, var virtualAB: VirtualABMessage? = null ) { companion object { @@ -18,13 +21,21 @@ data class MiscImage( ret.bcb = BootloaderMessage(fis) } FileInputStream(fileName).use { fis -> - fis.skip(32 * 1024) + fis.skip(VirtualABMessage.OFFSET) try { ret.virtualAB = VirtualABMessage(fis) } catch (e: IllegalArgumentException) { log.info(e.toString()) } } + FileInputStream(fileName).use { fis -> + fis.skip(MiscBootControl.OFFSET) + try { + ret.mbcb = MiscBootControl(fis) + } catch (e: IllegalArgumentException) { + log.info(e.toString()) + } + } return ret } } @@ -169,6 +180,89 @@ data class MiscImage( } } + data class MiscSlotMetadata( + var priority: Int = 0, + var tries_remaining: Int = 0, + var successful_boot: Int = 0, + var verity_corrupted: Int = 0, + var reserved: Int = 0, + ) { + constructor(inS: InputStream) : this() { + val info = Struct(FORMAT_STRING).unpack(inS) + priority = (info[0] as ByteArray)[0].toInt() + tries_remaining = (info[1] as ByteArray)[0].toInt() + successful_boot = (info[2] as ByteArray)[0].toInt() + verity_corrupted = (info[3] as ByteArray)[0].toInt() + reserved = (info[4] as ByteArray)[0].toInt() + } + + fun encode(): ByteArray { + return Struct(FORMAT_STRING).pack( + byteArrayOf(this.priority.toByte()), + byteArrayOf(this.tries_remaining.toByte()), + byteArrayOf(this.successful_boot.toByte()), + byteArrayOf(this.verity_corrupted.toByte()), + byteArrayOf(this.reserved.toByte()) + ) + } + + companion object { + private const val FORMAT_STRING = "bbbbb" + const val SIZE = 5 + } + + init { + check(SIZE == Struct(FORMAT_STRING).calcSize()) + } + } + + //offset 4KB, size 32B + data class MiscBootControl( + var magic: ByteArray = byteArrayOf(), + var version: Int = 0, + var recovery_tries_remaining: Int = 0, + var slot_info: MutableList = mutableListOf(), + var reserved: ByteArray = byteArrayOf(), + ) { + constructor(inS: InputStream) : this() { + val info = Struct(FORMAT_STRING).unpack(inS) + this.magic = info[0] as ByteArray + if (MAGIC != Helper.Companion.toHexString(this.magic)) { + log.warn(Helper.Companion.toHexString(this.magic)) + throw IllegalArgumentException("stream is not MiscBootControl") + } + this.version = (info[1] as ByteArray)[0].toInt() + this.recovery_tries_remaining = (info[2] as ByteArray)[0].toInt() + this.slot_info = mutableListOf( + MiscSlotMetadata(ByteArrayInputStream(info[3] as ByteArray)), + MiscSlotMetadata(ByteArrayInputStream(info[4] as ByteArray)) + ) + this.reserved = info[5] as ByteArray + } + + fun encode(): ByteArray { + return Struct(FORMAT_STRING).pack( + this.magic, + byteArrayOf(this.version.toByte()), + byteArrayOf(this.recovery_tries_remaining.toByte()), + this.slot_info.get(0).encode(), + this.slot_info.get(1).encode(), + this.reserved, + ) + } + + companion object { + private const val FORMAT_STRING = "4bbb${MiscSlotMetadata.SIZE}b${MiscSlotMetadata.SIZE}b16b" + private const val MAGIC = "00414242" + private const val SIZE = 32 + const val OFFSET = 4 * 1024L + + init { + check(SIZE == Struct(FORMAT_STRING).calcSize()) + } + } + } + //offset 32KB, size 64B data class VirtualABMessage( var version: Int = 0, @@ -179,9 +273,9 @@ data class MiscImage( ) { companion object { private const val FORMAT_STRING = "b4bbb57b" - private val log = LoggerFactory.getLogger("VirtualABMsg") private const val MAGIC = "b00a7456" const val SIZE = 64 + const val OFFSET = 32 * 1024L init { check(SIZE == Struct(FORMAT_STRING).calcSize()) diff --git a/bbootimg/src/main/kotlin/packable/MiscImgParser.kt b/bbootimg/src/main/kotlin/packable/MiscImgParser.kt index cf8a1e4..893e204 100644 --- a/bbootimg/src/main/kotlin/packable/MiscImgParser.kt +++ b/bbootimg/src/main/kotlin/packable/MiscImgParser.kt @@ -50,7 +50,11 @@ class MiscImgParser : IPackable { File(fileName).copyTo(out, true) RandomAccessFile(out.name, "rw").use { raf -> raf.write(misc.bcb.encode()) - raf.seek(32 * 1024) + raf.seek(MiscImage.MiscBootControl.OFFSET) + if (misc.mbcb != null) { + raf.write(misc.mbcb!!.encode()) + } + raf.seek(MiscImage.VirtualABMessage.OFFSET) if (misc.virtualAB != null) { raf.write(misc.virtualAB!!.encode()) }