米家智能家庭套装 Zigbee

米家智能家庭套装

礼品装包含:米家多功能网关、米家智能插座(Zigbee版)、米家无线开关、米家人体传感器、米家门窗传感器
米家智能家庭套装

拆解

  • 米家门窗传感器

    image-20200305234630485

  • 网关

    网关拆卸比较简单,卸掉三颗螺丝即可,但是使用的螺丝型号为U2.6,不怎么常见,好在之前买的米家螺丝刀里面有。

    image-20200306004255669

采用的芯片

  • Zigbee 模块

    zigbee 采用了 NXP 的 JN5169

    门窗传感器 CMMIIT 标准代码为 2015DP0290;无线开关 CMMIIT 标准代码为 2015DP0291;人体传感器 CMMIIT 标准代码为 2015DP0292;智能插座 CMMIIT 标准代码为2016DP3419。都是绿联生产的 2400-2475.5MHz 的 Zigbee 无线产品。

    image-20200306010251535

  • 网关主控

    WiFi 模块加了散热罩,CMMIIT 标准代码为 2015DP3043(M)。可以在国家无线电监测中心网站上查询到。

    image-20200306005229372

获取固件

将网关接入笔记本建立的热点进行抓包。发现固件升级采用 HTTP 明文传输,网关升级固件,包含 upd 固件和 MCU 固件两部分。

截取固件

导出固件

从流量中提取的固件地址复制到浏览器可以下载固件,一段时间后会失效。

http://cdn.cnbj0.fds.api.mi-img.com/miio_fw/212a951cb4fc5e5bdc62cecf206b412c_upd_lumi.gateway.v3.bin?GalaxyAccessKeyId=5721718224520&Expires=1583821054000&Signature=sykGFSopTsUcq2gamWtFS8BwQIA=&uniqRequestId=56175643

http://cdn.cnbj0.fds.api.mi-img.com/miio_fw/afa534fabcfb5d5230ee1f7715dad74e_mcu_lumi.gateway.v3.bin?Expires=1660464869000&GalaxyAccessKeyId=5721718224520&Signature=8N3Gj4oi5pZ/ar9O0CDUOxdH5bM=&uniqRequestId=56175643

串口

调试接口

暴露的调试引脚

通过逻辑分析仪获取波特率 115200。

逻辑分析仪引脚与波特率分析

使用串口时,不要接 TX 否则网关不会启动,启动之后在连接 Tx 可进行交互,等待灯圈闪烁后连接TX。

串口打印数据

1
2
3
4
5
6
7
8
9
10
11
12
13
dac_freq_set_ = 44100 , 44100 
03-30 13:17:49.526
{"id":29,"sid":"lumi.158d000232b856","model":"lumi.sensor_motion.v2","method":"props","params":{"device_log":"[1585545469,[\"event.motion\",[]]]"}}
03-30 13:17:49.548
{"id":30,"method":"props","params":{"music_op":"p_door_10","from.music_op":"5,2719655867,1585545469,lumi.158d000232b856.motion"}}
03-30 13:17:49.561
{"id":31,"method":"_sync.upLocalSceneRuningLog","params":[{"us_id":2719655867,"time":1585545469,"msg":[{"n":1,"e":0}]}]}
=eSL_WriteMessage= t=9f18,l=0,data=
=recv zigbee message:Free=174816 ,t=9f98;l=54;data= 01 87 20 a5 26 73 1c 71 82 1f d8 fd 9e 8b 54 49 7a 01 01 0f b0 f7 00 03 00 03 a0 21 00 15 8d 00 02 4a eb 9d 00 15 8d 00 02 4a eb 9d 65 46 1c f9 95 61 e4 76 23 11
03-30 13:17:57.003

###{"id":32,"method":"_async.store","params":{"bak_data":{"did":"80969777","model":"lumi.gateway.v3","data_type":"syscfg","total":1,"cur":0,"flag":"1585545477_1","data":"{\"spk_v\":60,\"gtw_v\":40,\"arm_v\":80,\"dbl_v\":60,\"clt_en\":1,\"nlt_rgb\":1686077311,\"dms_id_0\":0,\"dms_id_1\":10,\"dms_id_2\":20,\"dms_id_3\":30,\"dms_id_4\":40,\"cdl_time\":60,\"dbps_en\":0,\"awt_time\":5,\"alen_time\":30,\"alt_en\":1}","ver":15}}},T=137003
=recv zigbee message:Free=174192 ,t=8000;l=5;data= 00 00 9f 18 00

其中87 20 a5 26 73 1c 71 82 1f d8 fd 9e 8b 54 49 7a是 NWK KEY,在wireshark中配置密钥,解密流量。

串口命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
help 
system-conf
echo <on/off>
psm-get -p [optional partition name] <variable>
psm-set -p [optional partition name] <variable> <value>
psm-delete -p [optional partition name] <variable>
psm-erase -p [optional partition name]
psm-dump -p [optional partition name]
reboot reboot
miio-test (enter factory mode)
get_model model
ver app version
mac mac
LED01 LED RED ON
LED11 LED Green ON
LED21 LED BLUE ON
LED3 LED white ON
LED00 LED OFF
LUMEN illumination value
speaker
removezigbee
cmd_chk_zig
m_play m_play m_3
start_zigbee
erase_zigbee_psm
clear_zigbee_all
test_zigbee_rf test_zigbee_rf 26
set_sn set_sn sn123456
set_hd_ver set_hd_ver ver123
get_sn
get_hd_ver
toggle_print
wifi
set_led_mode
cali_temp cali_temp 25
get_zig_temp get_zig_temp
get_net_stat get_net_stat
test_flash test_flash
exit_factory exit_factory
get_acomp get_acomp
get_reg get_reg
set_reg set_reg
set_sale_mode set_sale_mode
get_sale_mode get_sale_mode
reset_lumi_bind reset_lumi_bind
set_zigbee_channel set_zigbee_channel
sound-play <filename>
fm <3:KEY_PAUSE;4:KEY_PREV;5:KEY_NEXT>
1
2
3
4
5
# system-conf 
SDK version: 3.5
Compiler version: 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 227977]
CPU clock frequency: 200000000Hz
Code execution mode: XIP

SWD - OpenOCD 调试

OpenOCD 配置

在网上找到 Marvell-88MW302 芯片的 OpenOCD 调试配置文件 wmcore.cfg,然后使用 FT232H dump固件或在线调试。

Openocd

固件dump

在芯片手册中找到 memory map,根据 memory map dump出固件等信息。

memory map

Flash 大小为 16M。dump Flash的时候可能会中断几次,此时需要根据实际情况,分段进行下载并拼接起来。然后将 raw 等区段dump出来,以供静态分析。

dump 中断,分段下载

固件分析

通过对比发现 flash的前字节与 upd 固件升级包相同,后续还有较多的数据,暂不知是什么用途,余下的部分该如何升级等。

对比固件

把剩余的部分拿出分析。0x1000000(16M)- 613824(0x95dc0 uhd固件的大小) = 16163392,使用 dd 进行分离。

1
2
3
4
root@ul00:~/iot/lumi# dd if=gateway_flash.bin bs=1 skip=613824 count=16163392 of=tmp.bin
16163392+0 records in
16163392+0 records out
16163392 bytes (16 MB, 15 MiB) copied, 37.6301 s, 430 kB/s

strings 查看字符串,libfaac 1.26.1 多次出现时,libfaac 用于音频编码。多次出现的 LAME3.99.5。LAME 是一种的 MP3 编码器,网关中有提示音和广播,这些部分是音频数据。mcu 关键的特征值(可读字符串)在 Flash 中没有找到,其块中也没找到,也应该在这块,猜测被加密了无法直接读取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
libfaac 1.26.1 (Dec 24 2008) UNSTABLE
libfaac 1.26.1 (Dec 24 2008) UNSTABLE
DR1175r1v1UNENCRYPTED00000JN5169
DR1175r1v1UNENCRYPTED00000JN5169
xxxx`|tddddXXXP@\TLDDD8880 <
truebLBT_IsEqObjectValue
=======================================================================
= (C) COPYRIGHT 2016 Lumi Tech =
= =
= System infomation =
= APP_VERSION--> V%d.%d.%02d =
= ModelID--> %s =
= Fireware BuildTime: %s %s =
= By Lumi tech Team =
sizeof(tsFactoryParam) = %d
sFactoryParam.u8FactoryTestOK = %d
sFactoryParam.u16RelayOffDelay = %d
sFactoryParam.u16PowerSlope = %d
sFactoryParam.i16PowerOffset = %d
sFactoryParam.u16VoltageSlope = %d
sFactoryParam.i16TempOffset = %d
sFactoryParam.bProtectEnable = %d
sFactoryParam.u8ProtectPower100w = %d
sFactoryParam.u8ProtectTempC = %d
sFactoryParam.u8HardwareVersion = %d
NT Size: %d u8NTNum %d u8ChildNum %d
EPCR = %x : EEAR = %x
pLoigicInputEvent->u16AttribteId= %x ,psHeaderV..u16AttribteId = %x
pLoigicInputEvent->u16Cluster= %x ,psHeaderV..u16PointType = %x
pLoigicInputEvent->u8EndPoint= %x ,psHeaderV..u8PointId = %x
pLoigicInputEvent->u16NetworkID= %x ,psHeaderV..u16ShortID = %x
u64TempLaunchId_2 = 0x%012llx , u8IfNumber = %d
Is Finded Launch ID
%s Source DataType Undefine!
%s Constant DataType Undefine!
%s u8Operate Undefine!
Find The Launch = 0x%012llx
No Finded Launch ID
u8AddressType Unkown!
sizeof(te_LumiNVMData_t) = %d
LumiNVMData.u8PrevOtaVersion: %x
u8SegDataLen= %d , sizeof(tsLBT_MapsStorage)= %d
PDM read bytes = %d
eStatusLBTReload=%d
vLoadLogicBindTableFromPDM() == FALSE
u8LUMI_GetNVM_u8ReStartReasonMask
sDeviceDesc.eNodeState = E_STARTUP
sDeviceDesc.eNodeState = E_REJOINING
sDeviceDesc.eNodeState = E_RUNNING
sDeviceDesc.eNodeState = E_UNKOWN
Radio Channel--> %d
EPAN Id--> 0x%016llx
Short Network Id--> 0x%x
IEEE Addr Id--> 0x%016llx
AvailbeNTSize--> 0x%04x
APP_ZCL_vInitialise Finished
App_Initialise Finished
Getting into BackOff State
Scan is over Channel
APP: APP_ReportTelegrame Task--> bOnOff:%d TriggerSource:%d
%s--> %d-%02d-%02d %02d:%02d:%02d %s
APP_ReportTelegrame_Task
Caution! Unpadded Extra [%02x]
u32CalculatedCrc = %08x
u32ReceivedCrc = %08x
got same sequence command!
--->bLumi_IsProtectFaultNow, Please don't Turn On
--->bLumi_IsProtectFaultNow, Please don't Turn On
---> bLUMI_ProtectFunction = %d
start up and send haertbeat
bLUMI_ChargeProtectCounter-> Now
save PDM when 150 heartbeat reach!
LBT_Find_u16ShortAddress %04x
Send Ping Device Request : 0x%016llx
Address Request failed: 0x%02x
%s : (0x%04x)Included In GroupTable
sRxFrame_Ifthen.asCondition[%d] u8Offset = %d
sRxFrame_Ifthen.asCondition
sRxFrame_Ifthen.sAction.sHV_A1
sRxFrame_Ifthen.sAction.sHV_A2
sRxFrame_Launch.asIf
bLUMI_RegisterGroupID
APP: Light Power Up = %d
APP: Watchdog timer has reset device!
OS_ISR(vISR_Timer4)--------------------------->
OS_ISR(vISR_Timer3)--------------------------->
EP EVT: Invalid evt type 0x%x
eLUMI_ReportSystemParameter2
eLUMI_ReportSystemParameter
eLUMI_ReportManufactoryParameter
eLUMI_AckLumiProtocol
APP_E_EVENT_BINDTABLE_ACTION -->EndPoint = %d, u16ClusterID=0x04%x, u16AtrributeID = 0x04%x, u8Cmd = %d
press 3s, Deleting the PDM
press 5s, Deleting the PDM
press 10s, Deleting the PDM
sAfZdpEvent.u16ClusterId %04x
IEE u16NwkAddrRemoteDev = 0x%04x 0x%016llx
Unhandle-->sAfZdpEvent.u16ClusterId:0x%04x
MgmtLeave - Rejoin: %d
MgmtLeave - Rejoin: 1
MgmtLeave - Rejoin: 2
sDeviceDesc.eNodeState = %d
%s: Got a message for DstAddr: 0x%04x Endpoint: %d <---> SrcAddr: 0x%04x Endpoint: %d u32TestAgentCount:%d
Handle_Report_Atrribute
SendReportingAttrGroup
eLUMI_ReportHeartBeat
libfaac 1.26.1 (Dec 24 2008) UNSTABLE
libfaac 1.26.1 (Dec 24 2008) UNSTABLE
LAME3.99.5UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUULAME3.99.5UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
ILAME3.99.5UUUUUUUUUUUUUUUUUUUUUU
z:QLAME3.99.5UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUd5
LAME3.99.5UUUUUUUUUUUUUUUUUUUUUUU
Y5LAME3.99.5UUUUUUUUUUUU(
LAME3.99.5UUUUUUUUU%P
LAME3.99.5UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUULAME3.99.5UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU

Zigbee 抓包

获取信道

将小米多功能网关上电,通过米家APP连接后,选择”网关”,然后在右上角点击三个点的图标,选择”关于”,进入新界面后多次点击底部的版本后,进入开发者模式。从多出来的 “网关信息” 中得到信道为 15。

image-20200330162734237

配置wireshark

将 CC2531 USB Donglg 插入电脑,并安装好驱动。 然后下载并安装TIMAC套件或PACKET-SNIFFER,打开 TiWsPc 对设备进行配置,选择 “Device Configuration” 将信道设置为 15,并点击 start。以上的目的是配置 CC2531 USB Donglg 抓取 15 信道的数据,并创建管道,将数据传递传递出来。最后在 Wireshark 快捷方式属性中的目标中添加-i\\.\pipe\tiwspc_data -k,使用 TiWsPc 创建的管道抓取 15信道上的 Zigbee 数据。

image-20200330161521346

添加密钥

双击 Wireshark就可以使用了,但现在数据还是加密的。由于小米多功能网关的密钥在串口打印出来了,我们可以用来解密流量,使用快捷键 CTRL+SHIFT+P 弹出首选项,在协议中选择 Zigbee,并配置密钥。在下图的 Key 中添加密钥。

image-20200330161714624

无线开关控制无线插座

单击无线开关实现无线插座的开关,以下是点击无线插座打开无线插座的流量。

打开插座:上报属性值为 0x000 的开合属性数据,类型为布尔型 0x10,开关指令为 0x01打开。

image-20200330174653495

无线开关控制智能插座:无线开关 0x9561 发送消息给网关 0x0000,然后由网关0x0000 转发消息给智能插座 0xfe75。详见附件数据包

image-20200713145853503

Ubiqua 比 Wireshark 更好用,但需要授权。

参考