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.

“AF_DataRequestSrcRtg()” 函数似乎有 BUG?

Other Parts Discussed in Thread: Z-STACK, CC2538, CC2530

协议栈:Z-Stack 3.0.2

协调器:CC2538

终端:CC2530

问题描述:

1、我调用 AF_DataRequestSrcRtg() 函数,“RelayCnt”参数为 1,“RelayCnt”参数 “pRelayList” 参数为 “0xd5eb”,然后抓包看见发出去的包并没有使用“source route” 功能。

请问这是为什么?

2、请问 “AF_DataRequestSrcRtg()” 函数的 “RTG_AddSrcRtgEntry_Guaranteed()” 有什么作用?

afStatus_t AF_DataRequestSrcRtg( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
uint8 options, uint8 radius, uint8 relayCnt, uint16* pRelayList )
{
    uint8 status;

    /* Add the source route to the source routing table */
    status = RTG_AddSrcRtgEntry_Guaranteed( dstAddr->addr.shortAddr, relayCnt,
    pRelayList );

    if( status == RTG_SUCCESS)
    {
        /* Call AF_DataRequest to send the data */
        status = AF_DataRequest( dstAddr, srcEP, cID, len, buf, transID, options, radius );
    }
    else if( status == RTG_INVALID_PATH )
    {
        /* The source route relay count is exceeding the network limit */
        status = afStatus_INVALID_PARAMETER;
    }
    else
    {
        /* The guaranteed adding entry fails due to memory failure */
        status = afStatus_MEM_FAIL;
    }
    return status;
}

  • AF_DataRequestSrcRtg 是增加 source route到source routing table在调用 AF_DataRequest之前。RTG_AddSrcRtgEntry_Guaranteed就是增加一个条目进去。
  • 如果你增加成功则会按照 source route发送,但是也会存在你的内存不足的情况无法添加,如果你source routing table已经有了该地址,重新调用RTG_AddSrcRtgEntry_Guaranteed则会更新它
  • 调用 RTG_AddSrcRtgEntry_Guaranteed 保存的源路由表是保存到这里对吧:

    #if defined ( ZIGBEEPRO ) || defined ( ZBIT )
        rtgSrcEntry_t rtgSrcTable[MAX_RTG_SRC_ENTRIES];
        uint16 rtgSrcRelayList[MAX_SOURCE_ROUTE];
    #endif

    那什么时候会删除?还会一直保存在这的吗?

  • 如果这个设备一直存在就有一直有,如果它退网就会被remove掉释放空间:
    ZDApp_LeaveUpdate
  • 那将“route record”数据上传到host保存有啥意义?最终还是会在 CC2538 里面存储路径,占用芯片内存。那还不如直接在“route record”命令里面直接调用“RTG_AddSrcRtgEntry_Guaranteed()”命令,然后再调用“AF_DataRequest()”的时候,它就会自动在“rtgSrcTable[]”里面寻找路径发出吗?
  • 举个简单的应用实例,你收到了很多个设备的route record通常是做一个数据库,然后进行查表比对而不是直接就去RTG_AddSrcRtgEntry_Guaranteed更新。当然你想是否上传到host还是收一个就去RTG_AddSrcRtgEntry_Guaranteed更新,这是你的自己应用决定的。
  • 其实我就是想减小 CC2538 内存的压力,因为子节点会有 100 多个,所以想将 “route record” 的源路由表存储到 host ,然后再调用 AF_DataRequestSrcRtg() 将其发送出去。
    我在英文论坛收到 Toby Pan 的回复,他说:
    RTG_AddSrcRtgEntry_Guaranteed() guarantees adding an entry into the source routing table (eg. if the table is full, this entry will replace the oldest entry in the table).
    如果 “rtgSrcTable[]” 满了就会重新覆盖最旧的地址是吗?那我是不是可以将 MAX_RTG_SRC_ENTRIES 设置为 1,那么就可以实现我上面的想法了?
  • 100 node 2538就算你都存储也问题不大吧,除非你应用程序特别多。是会覆盖第一条目,如果你设置为1,难道你要发生送之前先从host数据库拿到去填充吗?不建议你设置为1,可能会出现其他问题。试试看就知道了,没这么操作过。
  • 如果调用 “RTG_AddSrcRtgEntry_Guaranteed()” 函数就只是更新源路由列表的话,那么我直接调用 “AF_DataRequest()” 也是会使用到源路由路径的咯?那上面那个建议不就不成立了?那返回状态为 “Source Route Failure” 的 “network status” 命令时,还是无法更新路径啊?

    原贴:https://e2echina.ti.com/question_answer/wireless_connectivity/zigbee/f/104/t/176019

  • source route failure是你的链路不对,但是不会导致发送不到设备。如果已经证明你的加入的这个source record是无效的或者错误的,就没必要非要用这个错误路径去发。
  • 当你收到这个错误时建议是这样的,用NLME_RouteDiscoveryRequest重新去获取。
  • Alvin Chen 说:
    source route failure是你的链路不对,但是不会导致发送不到设备。如果已经证明你的加入的这个source record是无效的或者错误的,就没必要非要用这个错误路径去发。


    对啊,那我该怎么发?这时候我直接调用 “AF_DataRequest()” 函数是不是也会经过这个路径发?

    用了 “NLME_RouteDiscoveryRequest(dstAddr, MTO_ROUTE, 0x1E);”  重新寻找关于这个节点的 route request,它也不会返回 “route record” 吧?

  • 不会立即返回,extern ZStatus_t NLME_RouteDiscoveryRequest( uint16 DstAddress, byte options, uint8 radius );options填写0x01。

    我有个想法既然那个链路不对,就直接remove 掉它,等下次了record 再填进去,没试过,你可以去试试。
  • Alvin Chen 说:
    举个简单的应用实例,你收到了很多个设备的route record通常是做一个数据库,然后进行查表比对而不是直接就去RTG_AddSrcRtgEntry_Guaranteed更新。当然你想是否上传到host还是收一个就去RTG_AddSrcRtgEntry_Guaranteed更新,这是你的自己应用决定的。

    那每次调用 “AF_DataRequestSrcRtg()” 函数的时候也是要调用 “RTG_AddSrcRtgEntry_Guaranteed()” 进行更新的,如果会造成负荷的话,这样负荷会不会也是很重?

  • 1、看了他的回答我一脸懵逼!?那还需要“Af_DataRequestSrcRtg()”吗?“Af_DataRequestSrcRtg()”有什么用?

    2、我发现一个很奇怪的现象,就是我发送“relayCnt”为1,“pRelayList”为 0x1e99 的“Af_DataRequestSrcRtg()”命令,然后获取了“rtgSrcTable[]”里的该节点的链路也的确是“relayCnt”为1,“pRelayList”为 0x1e99,但是通过抓包发现发送出去的命令并没有启动“source route”!?

  • 1. 协议栈并没有自动适配调整使用 源路由表路径 或  其他路径, 主要根据调用不同的api来选择使用哪个表信息路径

    2. 发送数据前打印下源路由表信息看下

       

  • 我打印了源路由表来看,里面的路径的确是“relayCnt”为1,“pRelayList”为 0x1e99 ,但是发送出去的时候却没有使用此路径。
    还有你说的
    1. 协议栈并没有自动适配调整使用 源路由表路径 或 其他路径, 主要根据调用不同的api来选择使用哪个表信息路径
    没看懂。
  • MTO对于协调器端,主要增加了对 源路由的维护,至于使用源路由表路径 还是 路由表/相邻表路径是让用户自己来选择;
    Af_DataRequestSrcRtg() 使用源路由表路径;
    Af_DataRequest()使用非源路由表路径。
  • afStatus_t AF_DataRequestSrcRtg( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
    uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
    uint8 options, uint8 radius, uint8 relayCnt, uint16* pRelayList )
    {
    uint8 status;

    /* Add the source route to the source routing table */
    status = RTG_AddSrcRtgEntry_Guaranteed( dstAddr->addr.shortAddr, relayCnt,
    pRelayList );

    if( status == RTG_SUCCESS)
    {
    /* Call AF_DataRequest to send the data */
    status = AF_DataRequest( dstAddr, srcEP, cID, len, buf, transID, options, radius );
    }
    else if( status == RTG_INVALID_PATH )
    {
    /* The source route relay count is exceeding the network limit */
    status = afStatus_INVALID_PARAMETER;
    }
    else
    {
    /* The guaranteed adding entry fails due to memory failure */
    status = afStatus_MEM_FAIL;
    }
    return status;
    }

    “AF_DataRequestSrcRtg()”相较于“AF_DataRequest()”就只是调用多了一个“RTG_AddSrcRtgEntry_Guaranteed()”函数而已,TI 的技术人员说“RTG_AddSrcRtgEntry_Guaranteed()”函数是将源路由路径添加进源路由表的?
  • RTG_AddSrcRtgEntry_Guaranteed() 这个以实际测试为准;
    RTG_AddSrcRtgEntry_Guaranteed() 确实在创建更新源路由表条目,同时将 src route bit 置1
  • 刚刚我测试了,不调用“AF_DataRequestSrcRtg()”函数,在收到“route record”命令后,"rtgSrcTable []"列表的确有自动添加源路由路径条目,证明 toby Pan 说的是对的。
    但是还是那个问题,就是我发送“relayCnt”为1,“pRelayList”为 0x1e99 的“Af_DataRequestSrcRtg()”命令,然后获取了“rtgSrcTable[]”里的该节点的链路也的确是“relayCnt”为1,“pRelayList”为 0x1e99,但是通过抓包发现发送出去的命令并没有启动“source route”!?
  • 你需要提供完整的sniffer log 截图信息有限
  • Hi All,

    澄清一下这个问题,首先使用routing source 取决于你的rtgSrcTable是否有该地址的正确的记录。
    AF_DataRequestSrcRtg中的RTG_AddSrcRtgEntry_Guaranteed只是添加rtgSrcTable,从而保证有rtgSrcTable,保证了使用routing source。
    如果无法使用则说明该链路存在问题。
  • 这个是抓包文件,抓包软件是 wireshark;网络密钥是:fd:e2:82:29:e3:be:48:b0:36:14:54:0f:3f:c4:51:53no enable soure route.rar

    具体可以查看 501 行的读属性命令,是没有使能“source route”功能的,但是我查看了"rtgSrcTable []",“0xec7d”设备的条目为"relayCnt" 为1, "pRelayList" 为 "0x99e9"。而且我也是调用"relayCnt" 为1, "pRelayList" 为 "0x99e9"的“ Af_Data Request SrcRtg()”函数来进行发送的。但是还是没有使能“source route”功能。

  • 感觉你把源路由表 (mto机制)和 路由表(aodv)混淆了

    MTO网络是 所有节点端建立mto路径, 协调器端建立到达所有节点的源路径(这个源路径依赖route record,而route record的触发确由节点端来触发,默认场景下对协调器来说其到节点的源路径建立和更新时间上是不那么确定的);

    如果源路径不可用(source route failure),你建议的是发送AF_DataRequest(),这个会使用非源路径 (即aodv的路径 或 发起路径修复过程),这个处理本质上跟mto机制没什么关系,只是切换至aodv路由方式
  • 使用wireshark 打开比较奇怪(需要做特殊设置?):

  • 不需要什么特殊设置啊,wireshark 是 Version 2.6.7 的。
  • 发送 “AF_DataRequest()” 就会使用非源路径?
    在发送 “AF_DataRequest()” 前调用 “RTG_AddSrcRtgEntry_Guaranteed()” 就会使用“source route”?
  • 您好,看了您这个最佳答案,还是没明白这个问题是怎么解决的。
    我这边测试,也是发现按照“AF_DataRequestSrcRtg”发送,有时候设备总会不按照源路由的方式进行发送。抓包现象跟你的提问里一样