|
|
|
@ -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<MiscSlotMetadata> = 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())
|
|
|
|
|