Skip to content

Commit

Permalink
Merge pull request #20 from matejdro/screenshots
Browse files Browse the repository at this point in the history
add screenshot packets
  • Loading branch information
crc-32 authored May 8, 2021
2 parents 1ee8fb3 + 4ed11ed commit f3200e5
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
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.SUByte
import io.rebble.libpebblecommon.structmapper.SUInt
import io.rebble.libpebblecommon.structmapper.SUnboundBytes
import io.rebble.libpebblecommon.structmapper.StructMappable

class ScreenshotRequest : PebblePacket(ProtocolEndpoint.SCREENSHOT) {
/**
* Command. Only one command (take screenshot, value 0) is supported for now
*/
val command = SUByte(m, 0u)
}

class ScreenshotResponse : PebblePacket(ProtocolEndpoint.SCREENSHOT) {
val data = SUnboundBytes(m)
}

class ScreenshotHeader : StructMappable() {
/**
* @see ScreenshotResponseCode
*/
val responseCode = SUByte(m)

/**
* @see ScreenshotVersion
*/
val version = SUInt(m)

val width = SUInt(m)
val height = SUInt(m)
val data = SUnboundBytes(m)
}

enum class ScreenshotResponseCode(val rawCode: UByte) {
OK(0u),
MalformedCommand(0u),
OutOfMemory(0u),
AlreadyInProgress(0u);

companion object {
fun fromRawCode(rawCode: UByte): ScreenshotResponseCode {
return values().firstOrNull { it.rawCode == rawCode }
?: error("Unknown screenshot response code: $rawCode")
}
}
}

enum class ScreenshotVersion(val rawCode: UInt) {
BLACK_WHITE_1_BIT(1u),
COLOR_8_BIT(2u);

companion object {
fun fromRawCode(rawCode: UInt): ScreenshotVersion {
return values().firstOrNull { it.rawCode == rawCode }
?: error("Unknown screenshots version: $rawCode")
}
}
}

fun screenshotPacketsRegister() {
PacketRegistry.register(ProtocolEndpoint.SCREENSHOT) {
ScreenshotResponse()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ object PacketRegistry {
appFetchIncomingPacketsRegister()
putBytesIncomingPacketsRegister()
appReorderIncomingRegister()
screenshotPacketsRegister()
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.rebble.libpebblecommon.services

import io.rebble.libpebblecommon.ProtocolHandler
import io.rebble.libpebblecommon.packets.ScreenshotRequest
import io.rebble.libpebblecommon.packets.ScreenshotResponse
import io.rebble.libpebblecommon.protocolhelpers.PebblePacket
import io.rebble.libpebblecommon.protocolhelpers.ProtocolEndpoint
import kotlinx.coroutines.channels.Channel

class ScreenshotService(private val protocolHandler: ProtocolHandler) : ProtocolService {
val receivedMessages = Channel<ScreenshotResponse>(Channel.BUFFERED)

init {
protocolHandler.registerReceiveCallback(ProtocolEndpoint.SCREENSHOT, this::receive)
}

suspend fun send(packet: ScreenshotRequest) {
protocolHandler.send(packet)
}

fun receive(packet: PebblePacket) {
if (packet !is ScreenshotResponse) {
throw IllegalStateException("Received invalid packet type: $packet")
}

receivedMessages.offer(packet)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,44 @@ class SBytes(
}
}

/**
* Byte array without bounded size. It reads until whole packet buffer is read.
*
* This must be declared as last object
*
* Only for reading from watch.
*/
class SUnboundBytes(
mapper: StructMapper,
endianness: Char = '|'
) : StructElement<UByteArray>(
{ buf, el ->
throw UnsupportedOperationException("SUnboundBytes is read-only")
},
{ buf, el ->
val leftBytes = buf.length - buf.readPosition
val value = buf.getBytes(leftBytes)
el.set(if (el.isLittleEndian) value.reversedArray() else value)
},
mapper, 0, ubyteArrayOf(), endianness
) {

override fun toString(): String {
return "SUnboundBytes(value=${get().contentToString()})"
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is SUnboundBytes) return false
if (get() != other.get()) return false
return true
}

override fun hashCode(): Int {
return get().hashCode()
}
}

/**
* Represents a fixed size list of T
* @param T the type (must inherit Mappable)
Expand Down

0 comments on commit f3200e5

Please sign in to comment.