逆向工程 UPS 串行协议:Checksum/CRC?

Reverse engineer UPS serial protocol: Checksum/CRC?

我收到了一台 APC SMC1000 UPS 设备,我想用它来为基于微控制器的应用程序供电,并在关机前执行一些任务。 UPS既有串口也有USB口,不过串口协议好像没有记载。由于uC上没有USB-host,我想用串口与它通信

在使用 Python 脚本四处寻找之后,UPS 开始说话,我可以识别一些信息。但是,最终它似乎希望在继续之前收到一条消息,所以我想弄清楚该怎么做。

UPS 总是发送 19 字节的消息,其中第一个字节是 ID,接下来是 16 字节的数据,然后大概是 2 字节的一些未知校验和或 CRC。

[ Msg ID | 16 byte data | 2 byte checksum? ]

如何导出CRC或校验和类型?我已经尝试了一些方案并最终在没有运气的情况下在以下 ID 为 7f 的消息中使用了 reveng:

0x7f 0000000019c90013004e000001790000 3190
0x7f 0000000019ca0013004e000001790000 259b
0x7f 0000000019cb0013004e000001790000 19a6
0x7f 0000000019cc0013004e000001790000 0db1
0x7f 0000000019cd0013004e000001790000 01bc
0x7f 0000000019ce0013004e000001790000 f4c7
0x7f 0000000019cf0013004e000001790000 e8d2
0x7f 0000000019d00013004e000001790000 dcdd
0x7f 0000000019d10013004e000001790000 d0e8
0x7f 0000000019d20013004e000001790000 c4f3
0x7f 0000000019d30013004e000001790000 b8fe
0x7f 0000000019d40013004e000001790000 ac0e
0x7f 0000000019d50013004e000001790000 a015
0x7f 000000001c67001500530000017c0000 5eb8

如有任何有用的想法,我们将不胜感激!

我在这上面花了太多时间。但是,嘿,一旦你掉进了兔子洞......

感谢@rcgldr,我避免了查找 CRC 检查,而是决定查找各种简单的校验和。最终我得到了一个 Python 脚本,该脚本对上面的示例运行各种校验和并将其与最后 2 个字节进行比较。它没有成功,直到我将第一个字节添加到校验和中,给我一个 Fletcher 的 8 位校验和。 为此,我使用了 https://github.com/njaladan/hashpy 中的代码。

7f0000000019c90013004e000001790000 0x3190 PASS
7f0000000019cb0013004e000001790000 0x19a6 PASS
7f0000000019cc0013004e000001790000 0xdb1 PASS
7f0000000019cd0013004e000001790000 0x1bc PASS
7f0000000019ce0013004e000001790000 0xf4c7 PASS
7f0000000019cf0013004e000001790000 0xe8d2 PASS
7f0000000019d00013004e000001790000 0xdcdd PASS
7f0000000019d10013004e000001790000 0xd0e8 PASS
7f0000000019d20013004e000001790000 0xc4f3 PASS
7f0000000019d30013004e000001790000 0xb8fe PASS
7f0000000019d40013004e000001790000 0xac0a FAIL
7f0000000019d50013004e000001790000 0xa015 PASS
7f000000001c67001500530000017c0000 0x5eb8 PASS

它还表明其中一个样本的校验和无效。 不幸的是,我的印象是消息 7f 是对主机的某种挑战字符串。也许我也可以解决这个难题:)

协议 ID

到目前为止,我还通过检查数据和搜索 APC 的 PowerChute 报告的值来识别几个消息 ID。

  • 0x00:Header 带有协议信息(16 字节)
    • byte 0:未知(我检查的单元上总是 0A,可能是协议版本?)
    • 字节 1:消息大小
    • 字节 2:可用 ID
  • 0x40:序列号(14字节)
  • 0x41: 单位名称
  • 0x43: 单位类型
  • 0x45: 固件版本 1
  • 0x46:固件版本 2
  • 0x48:电池更换代码
  • 0x49:制造商
  • 0x7e:部分挑战(至)
  • 0x7f:部分挑战(来自)

也许我会随着进度更新此列表

2019 年 9 月 11 日更新

我现在正在 https://sites.google.com/site/klaasdc/apc-smartups-decode

上记录我的进度