搭载 PL1167 RF2.4G 芯片的灯光遥控器协议逆向分析
0. 简要介绍
买了个外观不错且价格无比诱人的 RF2.4G 灯光遥控器,准备用来控制我的鱼缸 LED 灯,无奈商家不提供相关资料,只卖配套的接收器,所以这里土法上马,自己逆向下其协议,权当学习。
1. 采集基本信息
拆开遥控器,看到了电路板,非常简单,主电路就两个 IC,一个 PL1167,一个磨掉了型号。不用想就可以确定磨掉了型号的 IC 必然是一个 MCU。
1.1 PL1167 芯片的概况
Google 了关键字发现 PL1167 是国产的低成本 RF 2.4G 通讯芯片。支持 SPI 与 I2C 接口。
PL1167 的官网不让下载查看数据手册,这里非常奇怪,一个民用的普通芯片居然不让直接下载数据手册,难道是有什么见不得人的地方?也许芯片设计是 rip off 过来的?呵呵。
通过网络搜索得知 PL1167 的寄存器与 LT8900/LT8920 兼容,所以下面的分析以 LT8920 的中文数据手册作为参考。
1.2 电路分析
通过对比 Datasheet 的典型应用电路和通过万用表判断引脚连接,确认 PL1168 与被抹去型号的单片机使用 SPI 总线接口相连接。
由于单个遥控器的单价仅 9 元,这里推测 MCU 使用的应该是最便宜的国产 8 位单片机。
1.3 测试运行
将示波器的探头接入电路上的晶振,按下遥控器按钮,使用示波器自动挡捕获波形。可以看到 12MHz 的 sine 波形,说明晶振已起振,RF 电路应该能够正常运行。更深入的射频方面的检查也没法具体执行,因为我的示波器只有 100M 模拟带宽。
按下遥控器按钮的同时遥控器上的 LED 点亮,且 SPI 总线的 SPI_CLK 时钟脚也有方波信号,说明单片机也基本能够正常工作。
2. 连接分析用的硬件
这里使用了国产山寨 Saleae 的 USB 逻辑分析仪,四个通道分别用飞线焊接的手法接上 PL1167 芯片的 SPI 总线相关引脚。

这里因为 PL1167 的封装很小,实际飞线是焊接在 MCU 的引脚上的。
3. 数据捕获
Saleae 软件设置为通过 PL1167 的 SPI_SS 的“Trigger on Negative Pulse Width”模式触发。
启动 Saleae 软件的捕获功能,并按下遥控器的某个键,单片机到 RF IC 的 SPI 总线上出现了如下数据:

这里手工整理如下:
07 00 00 34 80 80 32 07 5A 2D 12 01 09 0E B8 07 01 04
07 00 00 34 80 80 32 07 5A 2D 12 01 09 0E B8 07 01 27
07 00 00 34 80 80 32 07 5A 2D 12 01 09 0E B8 07 01 4A
查 LT8900 的数据手册得知 SPI 总线上的数据是以三个字节为一个 SPI_SS 周期进行发送/接收的。格式为:
<寄存器编号> <参数字节1> <参数字节2>
这里有个例外是 50 寄存器,可以通过一个 SPI_SS 周期读写单个字节,其他的都是以两个字节 16 位为一个 SPI_SS 周期进行读写操作。
以上三行数据为一个重复 Pattern,重复了多次出现。分析原因应该是没有接收方, ACK 失败,RF 芯片多次重试发射造成的。
4. 数据分析
第一组字节 07 00 00
0x07 表示操作寄存器 7,00 00 表示命令芯片进入 idle 状态。
第二组字节 34 80 80
0x34 表示操作寄存器 52,0x80 二进制为 10000000B,表示同时清空 TX 和 RX 两个 FIFO 缓冲区
第三组、第四组、第五组字节 32 07 5A
0x32 表示操作寄存器 50,意图为写入 FIFO 缓冲区,也就是把数据给 RF 芯片准备发送。
综上分析,也即是按下一个按钮,会无线发送 8 字节的数据,即:
07 5A 2D 12 01 09 0E B8
第一个字节 07 推测就是给接收方使用的数据长度,后续是指令数据。
遥控器不同的按钮发送的数据应该就是只有这里不同。
第六组字节 07 01 04
0x07 还是表示操作寄存器 7,0x01 表示命令芯片进入 TX 状态进行发送,后面 0x04 表示频道。
遥控器会分别依次尝试 0x04、0x27、0x4A 三个无线频道。如果没有接收方,就会尝试多次重复发送。
5. 后话
第二天晚上准备接着分析的时候电源开错了,送了个 14V 进去当场烧短路,就又淘宝买了两个遥控器在路上,土逼抗体牛。