feat(sdk): 同步 iOS 改动 — owner→brand 重命名 + 硬绑前 brand 校验 + README 内部细节抹除

- DuooomiBleConfig.owner → brand(语义:设备品牌名),HTTP header x-owner 不变
- bind() 前置 verifyBrand:缺 deviceInfo 先 getDeviceInfo,与 config.brand 严格匹配,
  不一致主动 disconnect 并抛 DuooomiBleError.BrandMismatch
- README 抹除软绑/对账/UpgradeRecord 等内部实现细节,仅保留厂商面向的公开 API
  (功能代码完全保留:fetchLatestFirmware 内部三段串、unbind 软解、tryReportPendingUpgrade)
- README 顶部加 demo 优先验证提示

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
km2023
2026-05-09 12:03:26 +08:00
parent d336ac358e
commit e63865092c
8 changed files with 45 additions and 59 deletions

View File

@@ -83,7 +83,7 @@ class DuooomiBleSDK(context: Context, val config: DuooomiBleConfig) {
private var flushJob: Job? = null
init {
BleLog.i("SDK initialized (apiHost=${config.apiHost}, owner=${config.owner})", "SDK")
BleLog.i("SDK initialized (apiHost=${config.apiHost}, brand=${config.brand})", "SDK")
setupDisconnectHandler()
// 启动时把持久化记录回放到 StateFlow
_upgradeRecords.value = upgradeRecordStore.all
@@ -253,6 +253,7 @@ class DuooomiBleSDK(context: Context, val config: DuooomiBleConfig) {
*/
suspend fun bind(userId: String): BindingResponse {
ensureConnected()
verifyBrand()
BleLog.d("Sending bind (userId=$userId)", "Command")
val data = sendAndWait(CommandType.BIND_DEVICE) {
deviceInfoService.bindDevice(userId)
@@ -732,6 +733,19 @@ class DuooomiBleSDK(context: Context, val config: DuooomiBleConfig) {
}
}
/**
* 校验设备 brand 与 SDK 配置 brand 是否一致;缺失则先拉一次 deviceInfo。
* 不一致时主动断连并抛 [DuooomiBleError.BrandMismatch]。
*/
private suspend fun verifyBrand() {
val actual = _deviceInfo.value?.brand ?: getDeviceInfo().brand
val expected = config.brand
if (actual == expected) return
BleLog.w("Brand mismatch: expected=$expected, actual=$actual; disconnecting", "Command")
runCatching { disconnect() }
throw DuooomiBleError.BrandMismatch(expected = expected, actual = actual)
}
private fun parseJsonResponse(data: ByteArray): JSONObject {
// Device responses may contain null bytes
val cleaned = data.filter { it != 0.toByte() }.toByteArray()