Files
abox-mgr/docs/protocol/absdk-0630.md
T
KremeCN 0144ea992c docs: reorganize project documentation (#15)
## Summary
- add a root README with project overview, setup, usage, architecture, security, and contribution guidance
- replace stale planning and requirement notes with current 1.0 project overview
- update architecture and hardware validation docs to match the implemented app
- remove obsolete UI branch notes and the old Java/XML AsyncTask example
- remove the superpowers documentation and move vendor ABSDK references into docs/vendor
- preserve vendor Markdown and XLS content byte-for-byte

## Verification
- Markdown relative links checked
- vendor files verified as 100% Git renames
- git diff --check passed
- no application tests run; documentation-only change

Reviewed-on: #15
Co-authored-by: KremeCN <3265494849@qq.com>
2026-08-28 10:57:47 +08:00

8.7 KiB
Raw Blame History

ABSDK 0630 已确认事实与边界

1. 文档范围

本文记录 libABSDK0630.jar、厂商接口文档和仓库历史 Sample 中能够复核的事实,并明确仍待真实环境确认的内容。

证据来源:

  • JAR:samples/abox-sdk-sample/login-mac/libs/libABSDK0630.jar;
  • 厂商文档:docs/vendor/ABSDK接口部分_0630.md;
  • 历史 Sample:samples/abox-sdk-sample/login-mac/;
  • 公开 API 使用 javap 验证,协议细节通过授权字节码分析验证。

本文只记录厂商 JAR 与局域网环境的已确认行为,不定义任何兼容服务端规范。尚未验证的内容见文末清单,不得作为产品实现承诺。

2. JAR 公开类型

com.dhc.absdk.ABSDK

JAR 提供 getInstance() 单例入口以及以下与 MVP 有关的方法:

ABRet loginWithUsername(String username, String password)
ABRet isValidateToken()
ABRet setHostInfo(String url, String hotelName, String roomNo, String apikey)
ABRet getSockStatus(String soDevName)
ABRet sockCtrl(String soDevName, String status)
ABRet getThStatus(String thDevName)
ABRet sendIr(String irDevName, String irKey)
ABRet studyIrByIrDevName(String irDevName, String irKey)
ABRet downloadIrCodes(List<IrInfo> irInfos)

JAR 还包含窗帘、开关、射灯、门磁、人体活动和一氧化碳相关接口,但不属于当前 MVP。

JAR 没有公开的设备列表、设备发现、logout 或 Token setter API。

com.dhc.absdk.ABRet

String getCode()
String getMsg()
Map<String, Object> getDicDatas()

"00000" 表示调用成功;其他字符串代码表示失败。Bridge 不向领域层泄漏 ABRet、Map 或厂商类型。

com.dhc.absdk.IrInfo

String irDevName
String key
String code
String status

下载结果的 status 是字符串:"0" 表示失败,"1" 表示成功。

3. 文档与 JAR 差异

厂商 Markdown 文档把温湿度方法写成:

getThStatusByDevName(String)

JAR 实际公开的方法是:

getThStatus(String)

Bridge 必须以实际 JAR 方法为准。

setHostInfo 是 JAR 的公开方法,但未出现在厂商 Markdown 接口清单中。

4. 全局状态与线程边界

JAR 使用单例 ABSDK,登录成功后把 Token 保存在 SDK 的静态状态中;后续请求从该全局状态读取 Token。HTTP Client 和 HTTP Context 也由 SDK 共享。

由此得到当前 Bridge 约束:

  • 任一时刻只维护一个活动 ABSDK 会话;
  • 所有 SDK 调用必须在后台执行;
  • 所有 SDK 调用默认串行化;
  • 切换提供方前必须退出 Bridge 本地会话;
  • JAR 没有 logout,Bridge 的 logout 只能清除本地会话并阻止后续调用;
  • Bridge 不通过反射访问或清理 SDK 私有 Token;重新登录会覆盖 SDK 中的 Token。

JAR 自身是否保证并发线程安全仍未得到厂商确认。

5. 传输事实

字节码确认 SDK 的基础地址硬编码为:

http://a-box.com.cn/abox/index.php/

SDK 使用 Apache HttpClient 4.x,所有已检查业务请求均为 POST。归档 Sample 同时包含:

httpclient-4.3.6.jar
httpcore-4.3.3.jar
commons-codec-1.6.jar
commons-logging-1.1.3.jar

JAR 内含宽松的 TLS 信任实现。正式产品不得把这一历史传输行为扩展为 App 其他网络请求的安全策略,也不得记录密码、Token、API Key 或敏感红外载荷。

App 组合根绑定真实 Bridge 时使用 @CleartextAbsdkTransport 作为编译期 opt-in 门禁,并声明 INTERNET 权限与明文传输许可。该标记只防止误接入,不会为链路提供加密;允许明文是项目所有者对当前局域网集成约束的明确风险接受,不代表传输具备机密性或完整性。

6. setHostInfo 的已确认行为

setHostInfo(url, hotelName, roomNo, apikey) 向以下端点发送初始化请求:

POST abjhsdk/init

四个参数作为表单字段提交:

url
hotelName
roomNo
apikey

其中第一个参数只写入请求字段 url,不会修改 SDK 的硬编码 HTTP 基础地址(见第 5 节)。因此该公开 API 不能用于切换请求目标。

仍未确认:

  • 正式业务中四个字段的具体语义;
  • ABox 官方环境是否要求每次启动调用;
  • hotel、room 和 API Key 的正式取值;
  • 初始化失败对后续登录和设备操作的影响。

Bridge 不实现或调用 setHostInfo。

7. 局域网网关观测证据(2026-08-24)

以下为 2026-08-24 在网关所在局域网内获得的观测结果,仅描述当天环境,不构成通用承诺:

  • 网关地址 192.168.100.1 在端口 80 和 443 上可达;
  • 未携带 Token 直接 POST http://192.168.100.1/abox/index.php/abjhsdk/user/validate 返回 code=00000、status=0;
  • feat/moler-infrared-control 分支的真实硬件测试表明:当前网络环境下,厂商 JAR 能够到达真实网关并完成红外相关操作。

同时必须保留以下边界:

  • JAR 仍然硬编码基础地址 a-box.com.cn;它在该环境中被映射到局域网网关的机制属于外部环境依赖,机制未知,且不受 setHostInfo 影响;
  • 尚未建立 JAR 可用的通用基础地址或主机配置能力,也没有完成携带授权凭据的登录冒烟验证;
  • 观测结果不能外推为“任意网络下均可连通”,后续环境变化须重新验证。

8. MVP 端点与数据

SDK 方法 端点 关键参数或返回
setHostInfo abjhsdk/init url、hotelName、roomNo、apikey
loginWithUsername abjhsdk/user/login username、SDK 内部 MD5 处理后的 password;返回 token
isValidateToken abjhsdk/user/validate 返回 status:0/1
getSockStatus abjhsdk/sock/properties name;返回 status:0/1
sockCtrl abjhsdk/zigbee/sock/{device} status:0/1
getThStatus abjhsdk/th/properties name;返回 temperature、humidity
sendIr abjhsdk/ir/{device}/send irKey
studyIrByIrDevName abjhsdk/ir/{device}/study irKey
downloadIrCodes abjhsdk/ir/{device}/download 每项发送 irKey、irCode

downloadIrCodes(List<IrInfo>) 并不是单次批量 HTTP 请求。JAR 按输入顺序逐项调用下载端点,并返回每项 status。只要有任一项失败,总体代码为 20204,同时 dicDatas["ret"] 仍包含逐项结果。

9. 请求签名

字节码显示 SDK 会:

  1. 取得秒级时间戳;
  2. 对业务参数键排序并组装签名原文;
  3. 加入端点、时间戳和 SDK 内部 secret;
  4. 使用 MD5 生成摘要;
  5. 按时间戳计算的位置插入时间片段并添加固定前缀;
  6. 在请求的 system 数据中提交签名、时间戳和 Token。

这些事实用于判断协议边界,本轮不重新实现签名算法,也不对外宣称兼容性。任何需要复现该协议行为的工作开始前,必须先建立脱敏签名测试向量并复核每个字段和编码细节。

10. 响应结构

字节码解析的响应结构为:

{
  "code": "00000",
  "msg": "...",
  "data": {}
}

data 被转换为 ABRet.dicDatas。解析或请求失败时,SDK 可返回 20000 和请求失败信息。

当前 Bridge 对成功数据进行防御性解析:缺失字段、未知状态或错误类型不会导致 ClassCastException 泄漏到调用方。

11. 错误码来源

完整错误码表来自厂商文档和历史 AboxConstants.java。Bridge 保留原始 externalCode,并映射为以下领域分类:

  • Token 无效;
  • 认证失败;
  • 网络错误;
  • 请求参数错误;
  • 设备不存在;
  • 设备离线;
  • 无数据;
  • 操作失败;
  • 未知错误。

错误 msg 只作为诊断 detail,不直接作为最终 UI 文案。

12. 历史 Sample 观察

历史 Sample:

  • 直接调用 ABSDK.getInstance();
  • 使用 Executor 或 AsyncTask 把同步调用移出 UI 线程;
  • 没有调用 setHostInfo;
  • logout 是空实现;
  • 使用普通 SharedPreferences 明文保存密码;
  • 全局允许明文网络。

正式实现只复用已确认的 SDK 调用事实,不复制 AsyncTask、明文凭据或全局明文网络配置。

13. 仍待确认

  • ABox 官方初始化的完整流程和参数;
  • 文档所称 Token 两小时有效期在真实环境中的精确表现;
  • Token 失效时各设备接口实际返回的代码;
  • SDK 的厂商线程安全保证;
  • 授权凭据下完整的 ABox 登录与设备操作冒烟验证;
  • JAR 硬编码域名与局域网网关地址之间的映射机制(第 7 节);
  • 网络环境变化(不同网段、DHCP、路由策略)下连通性是否保持;
  • ABSDK 和附属 JAR 的生产分发许可;
  • 所有端点的完整表单编码和可重复签名测试向量。

这些事项验证前不得作为产品实现承诺。