这里会显示出您选择的修订版和当前版本之间的差别。
jaysnote:zed_offline [2018/11/12 17:31] jaylee 创建 |
jaysnote:zed_offline [2021/06/22 23:14] |
||
---|---|---|---|
行 1: | 行 1: | ||
- | < | ||
- | |||
- | ## 理清思路 | ||
- | |||
- | 基本理清了所有流程,文杰观察的直接现象是多功能传感器(ZigBee End-Device,以下简称ZED)通过小米86盒开关 路由设备(ZigBee Router,以下简称ZR)关联加入网络很容易脱离网络。 | ||
- | |||
- | 首先,需要理清的`ZR`在IEEE-802.15.4 规定为`RFD` (精简功能设备),精剪功能主要在不能中继数据,作为树状网络拓扑的终端存在,同时受限于功耗,通常会选择大部分时间休眠以节约功耗。为了保证设备休眠能够正常接收数据,所以接收数据的时候选择间接交易,也就是父节点不直接向终端设备发送数据,是唤醒后的终端设备主动去轮询父节点字节是否有数据需要接收。所以其必须依赖父节点完成正常的通信业务, | ||
- | |||
- | 通常地,如果ZED多次才能够父亲轮询数据失败,机会考虑其成为孤儿并且考虑重新加入网络,基于此特性在TI 协议栈被 描述为可移动设备(`Portable Devices`)。 | ||
- | |||
- | * **Z-Stack | ||
- | |||
- | * **ZigBee Specification 2012** -> | ||
- | |||
- | * **Z-Stack | ||
- | * **ZigBee Specification 2012** -> | ||
- | |||
- | ### 不允许加入 | ||
- | |||
- | 下面是同父节点失去联系的ZED重新重新加入网络的流程,不幸的是,没有成功加入网络,还直接被**踢出**了网络。 | ||
- | |||
- | ![](http:// | ||
- | |||
- | 1. 我成为孤儿了; | ||
- | 2. 小米插座:让我作为你的父亲吧,给你取个新的名字; | ||
- | 3. 我有新名字了; | ||
- | 4. 小米插座:这事我还得通信下信任中心(Trust Center)登记下,让他给你一个通信密钥; | ||
- | 5. 信任中心:这事我不同意,现阶段我们**不允许**任何人加入,@小米插座 剔除了他; | ||
- | 6. 好的,离开网络; | ||
- | |||
- | 设备离线,发起了rejoin,通过关联小米路由加入网络,小米路由发起请求密钥(`update device`)并且通过如下的`Status` 标记为`Unsecured Rejoin`。 | ||
- | |||
- | ![](images/ | ||
- | |||
- | 成功收到如上`update device` 命令后,ZStack根据实际的`Status` 选择不同的处理,如果是`Secure join` ,理论上不会任何操作。 | ||
- | |||
- | ```c | ||
- | // | ||
- | void ZDSecMgrUpdateDeviceInd( ZDO_UpdateDeviceInd_t* ind { | ||
- | ZDSecMgrDevice_t device; | ||
- | // Trust Center should identify the type of JOIN/REJOIN and | ||
- | // Transport the NWK key accordingly, | ||
- | // APSME_UD_STANDARD_UNSECURED_JOIN | ||
- | // | ||
- | if ( ind-> | ||
- | if ( ind-> | ||
- | device.secure = TRUE; | ||
- | } | ||
- | ZDSecMgrDeviceJoin( &device ); | ||
- | } | ||
- | } | ||
- | ``` | ||
- | |||
- | 但是状态如果是`Unsecure join` 这里会直接交由信任中心(Trust Center) 处理。信任中心会根据`ZDSecMgrDeviceValidate` 的结果来决定添加设备(`ZDSecMgrAddrStore`)并且交换传输密钥 (`ZDSecMgrSendNwkKey`)还是直接踢出设备(`ZDSecMgrDeviceRemove`)。 | ||
- | |||
- | ```c | ||
- | // | ||
- | ZStatus_t ZDSecMgrDeviceJoin( ZDSecMgrDevice_t* device ) { | ||
- | ZStatus_t status = ZSuccess; | ||
- | uint16 | ||
- | |||
- | // attempt to validate device that joined/ | ||
- | if ( device-> | ||
- | status = ZDSecMgrDeviceValidate( device ); | ||
- | } | ||
- | |||
- | if ( status == ZSuccess ) { | ||
- | // Add the device to the address manager | ||
- | ZDSecMgrAddrStore( device-> | ||
- | //send the nwk key data to the joining device | ||
- | status = ZDSecMgrSendNwkKey( device ); | ||
- | } | ||
- | } | ||
- | if ( status != ZSuccess ) { | ||
- | // not allowed or transport key failed, remove the device | ||
- | ZDSecMgrDeviceRemove( device ); | ||
- | } | ||
- | ``` | ||
- | |||
- | `ZDSecMgrDeviceValidate` | ||
- | |||
- | ```c | ||
- | // | ||
- | ZStatus_t ZDSecMgrDeviceValidate( ZDSecMgrDevice_t* device ) { | ||
- | ZStatus_t status; | ||
- | |||
- | if ( ZDSecMgrPermitJoiningEnabled == TRUE ) { | ||
- | // For test purpose, turning off the zgSecurePermitJoin flag will force | ||
- | // the trust center to reject any newly joining devices by sending | ||
- | // Remove-device to the parents. | ||
- | if ( zgSecurePermitJoin == FALSE ) { | ||
- | status = ZNwkUnknownDevice; | ||
- | } | ||
- | } else { | ||
- | status = ZNwkUnknownDevice; | ||
- | } | ||
- | return status; | ||
- | } | ||
- | ``` | ||
- | |||
- | 而控制如上`ZDSecMgrPermitJoiningEnabled`和`zgSecurePermitJoin` 正是我们的[Web界面](http:// | ||
- | |||
- | ![](http:// | ||
- | |||
- | ```c | ||
- | // | ||
- | NLME_PermitJoiningRequest(60); | ||
- | ZDP_MgmtPermitJoinReq( & | ||
- | ``` | ||
- | |||
- | |||
- | |||
- | ## PermitJoin是如何控制TC的工作状态 | ||
- | |||
- | ``` | ||
- | // | ||
- | NLME_PermitJoiningRequest(60); | ||
- | ZDP_MgmtPermitJoinReq( & | ||
- | ``` | ||
- | |||
- | |||
- | |||
- | 先说结论,如上的Web页面控制的`允许入网` 功能对应的代码其实是控制了三个功能; | ||
- | |||
- | * 协调器的Mac层允许关联加入`NLME_PermitJoiningRequest`; | ||
- | |||
- | ![](http:// | ||
- | |||
- | * 广播允许加入命令,同步该允许使能到每一个路由 `ZDP_MgmtPermitJoinReq`; | ||
- | |||
- | ![](http:// | ||
- | |||
- | * 控制信任中心的使能标志; | ||
- | |||
- | 该使能标志通过`ZDP_MgmtPermitJoinReq` 通过其第三个使能参数决定的。 | ||
- | |||
- | ``` | ||
- | TcSignificance – This is a boolean value. If it is set to 0x01 and the remote device is the trust center, the command | ||
- | affects the trust center authentication policy as described in ZigBee Specification Section 2.4.3.3.7.2. | ||
- | ``` | ||
- | |||
- | 对于第三点,是如何影响到信任中心(Trust Center)功能使能的。需要继续review代码。 | ||
- | |||
- | ```c | ||
- | // | ||
- | void ZDO_ProcessMgmtPermitJoinReq( zdoIncomingMsg_t *inMsg ) { | ||
- | if ( tcsig == TRUE ) { | ||
- | ZDSecMgrPermitJoining( duration ); | ||
- | } | ||
- | ``` | ||
- | |||
- | 上面代码显示在收到`PermitJoin` 后的信任中心选择通过`tcsig`标志位来处理是否禁止/ | ||
- | |||
- | 也就是`ZDP_MgmtPermitJoinReq` 第三个形参,我们设置为**FALSE** 即表示通过`permit join` 命令不控制TC功能。 | ||
- | |||
- | ``` | ||
- | ZDP_MgmtPermitJoinReq( & | ||
- | ``` | ||
- | |||
- | ### 允许加入 | ||
- | |||
- | 如下是为设置信任中心允许设备加入后的抓包, | ||
- | |||
- | ![](http:// | ||
- | |||
- | 1. 我成为孤儿了; | ||
- | 2. 小米插座:让我作为你的父亲吧,给你取个新的名字; | ||
- | 3. 我有新名字了; | ||
- | 4. 小米插座:这事我还得通信下信任中心(Trust Center)让他给你一个通信密钥; | ||
- | 5. 信任中心:允许加入,给你密钥; | ||
- | 6. 正常通信了; | ||
- | |||
- | </ | ||