1 一般想获取网络短地址基本上是父节点要干的事情,还有为什么需要ZDP_NwkAddrReq 用这个函数是因为其他2个函数一个查本身的网络地址,一个是从父节点从表里查询,但是如果遇到2级以上就查不到了,所以需要用ZDP_NwkAddrReq 查询子节点的网络地址,无论是子节点还是“孙子”节点,因为这个函数是启用无线广播,向网内广播的形式得到匹配的MAC地址节点返回短地址(网络地址)。
这里有几个帖子:http://bbs.feibit.com/thread-9537-1-1.html
http://bbs.feibit.com/thread-8889-1-1.html
http://www.deyisupport.com/question_answer/wireless_connectivity/zigbee/f/104/p/67805/159710.aspx#159710
三个帖子都在讨论这个函数,但是没有一个是结贴的,没有一个是说明白的。
首先 TI的W先生 ZDO_RegisterForZDOMsg(task_id, NWK_addr_rsp); 和另外2个帖子 有些出入NWK_addr_rsp 还是 NWK_addr_rsq
2 但是基本上3个帖子 都说明了 ZDP_NwkAddrReq 大致用法 借用帖子的格式
使用步骤:
1.在任务初始初始化时调用:ZDO_RegisterForZDOMsg( sapi_TaskID, NWK_addr_rsp ); //sapi_TaskID:任务ID
我采用的是 SimpleApp 在这个里面 void SAPI_Init( byte task_id ) 有
如下:
// Register callback evetns from the ZDApp
ZDO_RegisterForZDOMsg( sapi_TaskID, NWK_addr_rsp );
2.在任务的ZDO处理函数中,处理NWK_addr_rsp选项
case NWK_addr_rsp:
{
// Send find device callback to application
ZDO_NwkIEEEAddrResp_t *pNwkAddrRsp = ZDO_ParseAddrRsp( inMsg ); //调用解析函数
}
break;
这里就迷惑了 对面2个帖子
W先生说是在 ZDApp_ProcessOSALMsg( osal_event_hdr_t *msgPtr )的case ZDO_CB_MSG的ZDApp_ProcessMsgCBs( (zdoIncomingMsg_t *)msgPtr );进行处理。
网友说是在:在任务的ZDO处理函数中,处理NWK_addr_rsp选项
case NWK_addr_rsp
到底在什么位置?
3 关于网络地址到底存在什么位置 都没有说出来,不过我的理解是通过
协调器收到广播后节点的回应包采用 ZDO_ParseAddrRsp进行数据解析 存储在ZDO_ParseAddrRsp函数返回的结果中,
ZDO_NwkIEEEAddrResp_t *pNwkAddrRsp = ZDO_ParseAddrRsp( inMsg ); 这里是存贮在 *pNwkAddrRsp 中
这里对ZDO_NwkIEEEAddrResp_t 进行说明:
typedef struct {
uint8 status;
uint16 nwkAddr; 这个就是所有获取的段地址? 是不是这个我不太确认
uint8 extAddr[Z_EXTADDR_LEN];
uint8 numAssocDevs;
uint8 startIndex;
uint16 devList[];
} ZDO_NwkIEEEAddrResp_t;
我写这个帖子是想能明白到底咋整,这个函数,其次是想说对一些回复过的问题最好有一个结贴。希望大家研究一下这个问题
JACK xiao1:
能做为一个专题讲讲么 ,各位
VV:
1, 在整个协议栈里面你有看到过NWK_addr_rsq, 既然没有就应该怀疑它了,协议栈里面只会出现NWK_addr_rsp, rsp代表 response的意思。
在网络术语里面有很类似的 req, rsp, ind, cnf,等等,你可以去了解下。
2, 首先在数据的传输流程上,NWK_addr_rsp消息首先收到的是在物理层,然后到MAC,再到网络层,再到AF层,AF会根据数据的end point来分发数据。
所有ZDO的数据的end point规定都是0,所以AF层把这个数据交给ZDO层来处理,数据首先来到了ZDApp_event_loop( uint8 task_id, UINT16 events )函数中
的ZDApp_ProcessOSALMsg( (osal_event_hdr_t *)msg_ptr )进行处理。在这个函数进入以后,首先数据被判断为是一个AF的数据,那么进入ZDP_IncomingData( (afIncomingMSGPacket_t *)msgPtr );进行处理,进入这个函数以后会调用到ZDO_SendMsgCBs( &inMsg ); 在这个函数里面,会把ZDO_CB_MSG发送给所有注册了对应处理ZDO消息的callback函数的task中。 那么这边在ZDO层,这个消息是默认注册的,所以会有一个ZDO_CB_MSG发送给ZDO层自己,会发送到ZDApp_event_loop里面,这个时候处理的变成了ZDApp_ProcessMsgCBs( (zdoIncomingMsg_t *)msgPtr );,这个函数就可以对具体的ZDO的消息进行处理了,比方说处理NWK_addr_rsp。 另外有些用户不希望在ZDO层做很多代码的改动,直接希望能够在应用层处理这个ZDO_CB_MSG消息,所以需要在应用层初始化的时候,通过 ZDO_RegisterForZDOMsg( sapi_TaskID, NWK_addr_rsp ); 这样完成注册以后,直接在应用层的event loop里面就可以收到ZDO_CB_MSG,然后同样的方式可以通过switch case的办法去直接处理NWK_addr_rsp消息了。
所以两种方法都可以。
4, 是的。
JACK xiao1:
回复 VV:
首先 谢谢W 先生的回复。
我用的是 SensorDemo
这个版本我 这2天又查了些资料 好像大家都没说
#define ZDO_NWKADDR_REQUEST
#define ZDO_IEEEADDR_REQUEST
我按照W 先生说的流程及处理,但是现在问题来了 调用了
ZDP_NwkAddrReq(IEEADD, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 ); API后 就没有收到响应
抓包工具截图如下:
从图中可以看出 调用ZDP_NwkAddrReq 协调器发出的广播包正常发出,寻找MAC 地址 0x19,0x70,0xc2,0x01,0x00,0x4b,0x12,0X00 这里需要说明这个地址和SmartRF Flash Programmer 读出来的地址顺序要反过来,希望看到帖子的朋友注意一下这个细节。
但是节点未做任何回应。还是我理解错误,其实 data request 就是这个API函数 节点的回应,希望 W 帮我确认一下,谢谢。
我的具体流程如下:
1 定义 :在协调器和节点都定义
#define ZDO_NWKADDR_REQUEST
#define ZDO_IEEEADDR_REQUEST
2 void SAPI_Init( byte task_id ) 函数中 注册响应事件( 我在 协调器 和 节点 中都有注册)这个需要吗,还是只在协调器上注册?
ZDO_RegisterForZDOMsg( sapi_TaskID, NWK_addr_rsp );
ZDO_RegisterForZDOMsg( sapi_TaskID, Match_Desc_rsp );
ZDO_RegisterForZDOMsg(sapi_TaskID, IEEE_addr_rsp );
3 ZDApp_ProcessOSALMsg( osal_event_hdr_t *msgPtr ) 函数中做处理
case ZDO_CB_MSG:
ZDApp_ProcessMsgCBs( (zdoIncomingMsg_t *)msgPtr ); 这里是调用ZDApp_ProcessMsgCBs 函数对ZDO_CB_MSG的消息 进行处理
break;
4 ZDApp_ProcessMsgCBs( zdoIncomingMsg_t *inMsg ) 函数中获取 网络地址
case NWK_addr_rsp:
{ ZDO_NwkIEEEAddrResp_t *pNwkAddrRsp = ZDO_ParseAddrRsp( inMsg ); J_nwkadd=pNwkAddrRsp->nwkAddr; }
‘但是在线调试跟踪确定 是根本不进来 在 3 就不进入 case ZDO_CB_MSG
从这里我的调试 和 抓包分析 确定我 没有得到 节点的响应,不知道需要在节点上做什么处理才能正确得到回应包。
W 能帮我分析一下吗? 我是用串口来指挥 什么时候调用 ZDP_NwkAddrReq 函数的。
各位也帮我分析一下具体什么地方出了错?为何就是没有回应呢。 是不是还需要某些宏定义 打开一些功能才可以?
JACK xiao1:
回复 VV:
好的
JACK xiao1:
回复 VV:
点击图片可以产看大图,我了解下这些术语,谢谢啊W先生。
我现在将 .cfg
中的-DRFD_RCVC_ALWAYS_ON 修改为TRUE 还是不行(节点,协调器都修改了)
起初以为是休眠的问题但是还是,得不到响应包
我现在仿真研究一下 这个帖子
http://www.deyisupport.com/question_answer/wireless_connectivity/f/45/t/24384.aspx
JACK xiao1:
回复 VV:
W 先生谢谢你的耐心讲解,现在问题已经搞清楚了。
是因为休眠的问题,需要将节点设置成 -DRFD_RCVC_ALWAYS_ON=TRUE 禁止休眠,
这个是节点休眠期间肯定对广播包没有反应的,因为节点休眠了。
修改后 正确获取到了 节点的网络地址,可以结贴了。希望给大家一个结论。。
在我的项目中还未引入路由,协调器发送ZDP_NwkAddrReq 后节点不响应的原因。
但是我有个疑惑, 对于休眠节点也有对应的广播 0XFFFD 这个是如何实现呢。
0xFFFF: 广播数据发送至所有设备,包括睡眠节点0xFFFD: 广播数据发送至正在睡眠的所有设备0xFFFC: 广播数据发送至所有协调器和路由器
zhibin wang:
回复 JACK xiao1:
@JACK xiao1 你好,请问你的疑惑解决了么?
我现在也是只有设置 -DRFD_RCVC_ALWAYS_ON=TRUE 才能实现协调器获取到终端的短地址,但我想实现获取休眠终端的短地址,不知道该如何操作。
不管如何,先谢谢你。