Android 设备认证 SDK
SDK Version: 1.0.0
Package:com.xtalk.mesh.sdk.auth
认证负责选择可用 AT 编码、完成 Challenge 验签并读取 DID。频率、速率、工作模式等参数属于 Init SDK,不属于认证参数。
构造 BLE RadioTransport
BleRadioTransport 需要事件桥和实时发送标记回调。仅用于 Auth/Init 时可以提供无操作实现:
object NoOpRadioTransportEventBridge : RadioTransportEventBridge {
override fun addPacketListener(listener: RadioPacketListener) = Unit
override fun removePacketListener(listener: RadioPacketListener) = Unit
override fun addRealtimePacketListener(listener: RadioPacketListener) = Unit
override fun removeRealtimePacketListener(listener: RadioPacketListener) = Unit
override fun addCrcErrorListener(listener: RadioCrcErrorListener) = Unit
override fun removeCrcErrorListener(listener: RadioCrcErrorListener) = Unit
}
val radioTransport: RadioTransport = BleRadioTransport(
eventBridge = NoOpRadioTransportEventBridge,
clearRealtimeNoWaitMark = {},
markRealtimeNoWaitSend = { _ -> },
)
如果业务需要接收 RF 包或 CRC 事件,请把无操作事件桥替换为客户自己的 RadioTransportEventBridge 实现。
BLE 认证
连接和 GATT 就绪后,在后台线程执行:
val auth = withContext(Dispatchers.IO) {
DeviceAuthenticator.authenticateBleAndReadDid(
radioTransport = radioTransport,
timeoutMs = 30_000L,
)
}
if (!auth.ok) {
handleAuthenticationFailure(auth.reason)
} else {
val did = auth.deviceLongId
onAuthenticated(did)
}
需要合并并发认证请求时使用:
val ok = DeviceAuthenticator.authenticateBleAndReadDidExclusive(
radioTransport = radioTransport,
timeoutMs = 30_000L,
forceReauth = false,
)
设备重启、OTA 完成或认证状态失效后,可设置 forceReauth = true,或先调用 markAuthenticationRequired(reason, resetAtMode)。
UART 认证
客户实现 AtCommandTransport,SDK 不持有客户的 UART 驱动:
val uartTransport = object : DeviceAuthenticator.AtCommandTransport {
override val label: String = "uart"
override fun runAtCommand(
command: String,
timeoutMs: Long,
log: Boolean,
): List<String> = myUart.runAtCommand(command, timeoutMs, log)
}
val auth = DeviceAuthenticator.authenticateUartAndReadDid(
transport = uartTransport,
challengeTimeoutMs = 10_000L,
didTimeoutMs = 6_000L,
)
不要记录 Challenge 原始密钥或把完整认证响应上传到公开日志。认证成功后再进入设备初始化。
完整接口契约
AtCommandTransport
interface AtCommandTransport {
val label: String
fun runAtCommand(command: String, timeoutMs: Long, log: Boolean = true): List<String>
}
label 只用于可读日志,不得包含密钥。runAtCommand 必须串行发送一条命令、按 CR/LF 返回完整行,并在连接关闭、设备错误或超时时抛异常。Auth 会捕获异常并转换为 Result.reason。RadioAtCommandTransport(radioTransport) 是推荐适配器:Challenge 收集完整响应,其他命令快速失败。
认证方法
| 接口 | 前置/线程 | 参数 | 返回与失败 |
|---|---|---|---|
authenticateBleAndReadDid(radioTransport, timeoutMs = 30000) | BLE CONNECTED;后台线程 | 总流程预算 | 选择 AT 模式、按需 Challenge、读并应用 DID,返回完整 Result |
authenticateBleAndReadDidExclusive(radioTransport, timeoutMs = 30000, forceReauth = false) | 同上 | forceReauth 清旧状态 | 合并并发调用;joiner 最多等待 timeoutMs + 8000;仅返回 Boolean |
authenticateUartAndReadDid(transport, challengeTimeoutMs = 10000, didTimeoutMs = 6000) | UART 已打开;后台线程 | Challenge/DID 各自期限 | Challenge + DID,成功后应用 DID,返回 Result |
markAuthenticationRequired(reason, resetAtMode = true) | 重启、OTA 或恢复前 | 原因和是否重置 BLE AT 模式 | 清 Auth/无线 ready 状态 |
readDeviceLongId(transport, timeoutMs, log) | 已通过认证或设备允许读取 | transport、期限、日志 | 依次尝试 AT+EFUSESN?、AT+SN?;结构化 DID 或 null |
applyDeviceLongId(deviceLongId, source) | DID 已验证 | 32 位长 ID、来源标签 | 写入核心身份成功为 true |
Result.reason
| reason | 含义 | 安全处理 |
|---|---|---|
ok | Auth 和 DID 成功 | 进入 Init |
not_connected | 未进入 CONNECTED | 检查状态,必要时重连 |
ble_not_ready | GATT/AT 未就绪 | 断开重连,不连续空转 Auth |
at_path_unavailable | 普通/XOR AT 探测均不可用 | 检查固件兼容与链路 |
challenge_command_failed | Challenge 发送、设备错误或超时 | 保持未认证;确认链路后最多重试一次 |
challenge_verify_failed | 签名校验失败 | 不得绕过;断开并联系支持 |
did_read_failed | 两个 DID 查询都无合法结构化 ID | 不进入 Init;重连或检查固件 |
只有 ok == true 才允许继续。失败结果即使含中间 DID,也不能当作已认证身份。Android Auth 没有独立 cancel API;协程取消不保证中断底层阻塞调用。业务取消时停止后续步骤,等待返回再断开。Exclusive joiner 超时只返回 false,不会启动第二次并行 Challenge。