package com.example.medilightv2android.ble object CRC16 { private const val POLYNOMIAL: Int = 0x1021 private const val INITIAL_VALUE: Int = 0xFFFF fun calculate(data: ByteArray): Int { var crc = INITIAL_VALUE for (byte in data) { crc = crc xor ((byte.toInt() and 0xFF) shl 8) for (j in 0 until 8) { crc = if ((crc and 0x8000) != 0) { (crc shl 1) xor POLYNOMIAL } else { crc shl 1 } crc = crc and 0xFFFF } } return crc } fun calculate(string: String): Int = calculate(string.toByteArray(Charsets.UTF_8)) fun appendCRC(data: ByteArray): ByteArray { val crc = calculate(data) return data + byteArrayOf( (crc and 0xFF).toByte(), // Low byte first (Little Endian) ((crc shr 8) and 0xFF).toByte() // High byte ) } fun appendCRC(string: String): ByteArray = appendCRC(string.toByteArray(Charsets.UTF_8)) fun verify(data: ByteArray): Boolean { if (data.size < 2) return false val payload = data.copyOfRange(0, data.size - 2) val receivedCRC = (data[data.size - 2].toInt() and 0xFF) or ((data[data.size - 1].toInt() and 0xFF) shl 8) return calculate(payload) == receivedCRC } fun buildCommand(cmd: String, params: IntArray = intArrayOf()): ByteArray { val cmdBytes = "$cmd?".toByteArray(Charsets.UTF_8) val paramBytes = ByteArray(params.size * 2) for (i in params.indices) { paramBytes[i * 2] = (params[i] and 0xFF).toByte() // Low byte paramBytes[i * 2 + 1] = ((params[i] shr 8) and 0xFF).toByte() // High byte } return appendCRC(cmdBytes + paramBytes) } fun buildCommandASCII(cmd: String, asciiParams: String = ""): ByteArray { return appendCRC("$cmd?$asciiParams".toByteArray(Charsets.UTF_8)) } /** 파라미터를 16비트 Big Endian으로 추가 (펌웨어 테스터와 동일 포맷) */ fun buildCommandBE(cmd: String, params: IntArray = intArrayOf()): ByteArray { val cmdBytes = "$cmd?".toByteArray(Charsets.UTF_8) val paramBytes = ByteArray(params.size * 2) for (i in params.indices) { paramBytes[i * 2] = ((params[i] shr 8) and 0xFF).toByte() // High byte first paramBytes[i * 2 + 1] = (params[i] and 0xFF).toByte() // Low byte } return appendCRC(cmdBytes + paramBytes) } fun buildSimpleCommand(cmd: String): ByteArray { return appendCRC(cmd.toByteArray(Charsets.UTF_8)) } }