Files
VesiscanClinicalAndroid/app/src/main/java/com/medithings/vesiscan/ble/CRC16.kt
T
dw.jang bcbc7b440c refactor: 데모 브랜치 패키지 통일 com.example.medilightv2android → com.medithings.vesiscan
사용자앱 (feature/tab-navigation) 과 패키지 이름 일치. namespace + applicationId
둘 다 com.medithings.vesiscan 로 변경 (기존 데모 앱은 재설치 필요).

## 변경 범위
- Kotlin 148 파일: package + import 문 (714 occurrences)
- 디렉토리 이동: com/example/medilightv2android → com/medithings/vesiscan
  (main, test, androidTest 각각)
- app/build.gradle.kts: namespace, applicationId
- docs/FLAVOR_DEMO_STABLE.md: 참조 갱신
- V41DetectorCH4Test: BvDispatchResult.methodChosen → method (dto field name fix)

## 주의
- applicationId 가 바뀌므로 기존 데모 앱 (com.example.medilightv2android.demo) 은
  Android 관점에서 다른 앱으로 취급 — 재설치 시 PIN/설정 초기화됨.
- Fresh install 권장. 기존 앱 (com.example...) 은 별도로 uninstall 필요.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-02 14:30:43 +09:00

72 lines
2.6 KiB
Kotlin

package com.medithings.vesiscan.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))
}
}