This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

关于根据MAC地址获取网络地址及ZDP_NwkAddrReq 函数

 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;

 

我写这个帖子是想能明白到底咋整,这个函数,其次是想说对一些回复过的问题最好有一个结贴。希望大家研究一下这个问题

  • 能做为一个专题讲讲么 ,各位

  • 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, 是的。


  • 首先 谢谢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  函数的。

      各位也帮我分析一下具体什么地方出了错?为何就是没有回应呢。 是不是还需要某些宏定义 打开一些功能才可以?

  • 把你抓包的数据用另存为,保存下来,用附件上传可以吗??

    稍微花点时间,弄清楚下,data request, mac ack,link status, device Announce 这些是啥东西??

  • 点击图片可以产看大图,我了解下这些术语,谢谢啊W先生。

    我现在将  .cfg

    中的-DRFD_RCVC_ALWAYS_ON   修改为TRUE 还是不行(节点,协调器都修改了)

    起初以为是休眠的问题但是还是,得不到响应包

    我现在仿真研究一下 这个帖子

    http://www.deyisupport.com/question_answer/wireless_connectivity/f/45/t/24384.aspx

  • W 先生谢谢你的耐心讲解,现在问题已经搞清楚了。

    是因为休眠的问题,需要将节点设置成   -DRFD_RCVC_ALWAYS_ON=TRUE  禁止休眠,

     这个是节点休眠期间肯定对广播包没有反应的,因为节点休眠了。

    修改后 正确获取到了 节点的网络地址,可以结贴了。希望给大家一个结论。。

    在我的项目中还未引入路由,协调器发送ZDP_NwkAddrReq 后节点不响应的原因。

    但是我有个疑惑,  对于休眠节点也有对应的广播  0XFFFD 这个是如何实现呢。

            0xFFFF: 广播数据发送至所有设备,包括睡眠节点
      0xFFFD: 广播数据发送至正在睡眠的所有设备
      0xFFFC: 广播数据发送至所有协调器和路由器

  • @JACK xiao1   你好,请问你的疑惑解决了么?

    我现在也是只有设置 -DRFD_RCVC_ALWAYS_ON=TRUE 才能实现协调器获取到终端的短地址,但我想实现获取休眠终端的短地址,不知道该如何操作。

    不管如何,先谢谢你。