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.

地址类型为AddrNotPresent相关疑问

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

1.当地址类型为AddrNotPresent,协调器发送指令后,是不是所有绑定的终端都能收到?

2.地址类型为AddrNotPresent,目的地址的enpoint和短地址怎么设置?

3.地址类型为AddrNotPresent,如果协调器发送后所有绑定的终端都能收到,那么如何只控制一类终端(比如终端有开关,插座,灯)?

4.zclGeneral_SendOnOff_CmdOn命令发送后,终端给协调器的应答,协调器是哪里收到的?是不是case ZCL_CMD_DEFAULT_RSP?

 

  • 请看原文,应该能解答你的疑问:

    this is when the application is not aware of the final destination of the packet. The mode is set to AddrNotPresent and the destination address is not specified. Instead,the destination is looked up from a “binding table” that resides in the stack of the sending device.

    When the packet is sent down to the stack, the destination address and end point is looked up from the binding table and used. The packet is then treated as a regular unicast packet.
  • 这个意思就协调器发了之后,所有绑定的终端都能收到
    比如我有10个灯,10个插座,用AddrNotPresent类型发指令,插座和灯都是同开同关,这不是想要的
    我要10个灯一起控制,不改变插座的状态,我是不是在协调器端发10条单播指令给10个灯?
    因为组播和广播没有单播稳定,在协调器端发10条单播指令给10个灯,这个会不会延时比较大,
    而且效果不知道怎么样?所有灯能不能一起动作?
  • 协调器端发10条单播指令给10个灯,这个会延时比较大,10个灯要一起控制要用组播

  • user5367314 说:
    这个意思就协调器发了之后,所有绑定的终端都能收到
    比如我有10个灯,10个插座,用AddrNotPresent类型发指令,插座和灯都是同开同关,这不是想要的
    我要10个灯一起控制,不改变插座的状态,我是不是在协调器端发10条单播指令给10个灯?
    因为组播和广播没有单播稳定,在协调器端发10条单播指令给10个灯,这个会不会延时比较大,
    而且效果不知道怎么样?所有灯能不能一起动作?

    1.只要在绑定表里面的设备均可以收到,他是去查询绑定表,然后挨个发送,建议用组播来做。

    2.延时问题却决你的poll rate 以及路由中继等原因, 如果你想保持最好的实时性就去用路由设备。

  • AddrNotPresent是搜索绑定表,然后把信息发送给绑定的设备,如果绑定了多个设备,则相关设备都会收到

    控制多个设备的话,组播比较好,当然单播也可以,延时还好
  • 我这边就是基于3.0.2例程的,协调器是基于switch例程,终端是基于light例程
    我想协调器组播去控制终端,具体实现的步骤是怎么样的?请提供下思路,谢谢
  • 好的,我试试,另外请教个问题
    实现开关操作我可以用ZCL_CLUSTER_ID_GEN_ON_OFF cluster
    但是如果要穿自己的数据(比如几十个字节的数据)
    ZCL没有定义这样的,需要自己定义,ZCL规范里只是介绍了,
    但是没说具体怎么定义私有的cluster,是否可以指导下
  • 簡單一點你可以共用 ZCL_CLUSTER_ID_GEN_ON_OFF cluster 然後加個私有的attribute ID使用ZCL_DATATYPE_ARRAY這個類型数据就行
  • 例如开关灯的attribute ID为
    #define ATTRID_ON_OFF 0x0000
    1.私有的ID也不是随便定义的 私有的值的范围是多少?
    2.在zcl_general.h里定义了私有attribute ID,还需要对该ID做哪些处理吗?还是直接就能用了?
    3.是不是要在zcl_samplesw.c里做类似以下的处理即可?其他还有什么地方要处理吗?
    {
    ZCL_CLUSTER_ID_GEN_ON_OFF,
    { // Attribute record
    ATTRID_CLUSTER_REVISION,
    ZCL_DATATYPE_UINT16,
    ACCESS_CONTROL_READ | ACCESS_CLIENT,
    (void *)&zclSampleSw_clusterRevision_all
    }
    }
    4.针对第3条,下面的哪些参数是需要的,我这边就是协调器和终端互传私有数据,
    不清楚该用下面的哪些参数组合?
    /*** Attribute Access Control - bit masks ***/
    #define ACCESS_CONTROL_READ 0x01 // attribute can be read
    #define ACCESS_CONTROL_WRITE 0x02 // attribute can be written
    #define ACCESS_REPORTABLE 0x04 // indicate attribute is reportable
    #define ACCESS_CONTROL_COMMAND 0x08
    #define ACCESS_CONTROL_AUTH_READ 0x10
    #define ACCESS_CONTROL_AUTH_WRITE 0x20
    #define ACCESS_GLOBAL 0x40 // TI unique to indicate attributes that are in both, client and server side of the cluster in the endpoint
    #define ACCESS_CLIENT 0x80 // TI unique, indicate client side attribute
  • 1. 你可以查一下 ZCL spec,沒用到的原則上都可以
    2. 直接就能用
    3. 沒有
    4. 一般我會用READ/WRITE/REPORTABLE
  • 组播的话是不是用这个cluster ZCL_CLUSTER_ID_GEN_GROUPS ?
    另外你上面说的用ZCL_DATATYPE_ARRAY,测试了不行,应该用ZCL_DATATYPE_CHAR_STR
  • 组播的话你要用组播地址模式,跟ZCL_CLUSTER_ID_GEN_GROUPS無關,ZCL_DATATYPE_ARRAY测试怎樣不行?
  • 我看到你之前有回复过“剛看了一下源碼,zclSerializeData裡面沒有處理ZCL_DATATYPE_ARRAY,所以應該要用ZCL_DATATYPE_CHAR_STR”
    另外下面的代码是做什么用的
    CONST zclAttrRec_t zclSampleSw_Attrs[]
    CONST zclAttrRec_t zclSampleLight_Attrs[]
    你上面的回复说不需在上面的数组里加代码,只要定义attribute ID即可
    但是你又说一般你會用READ/WRITE/REPORTABLE,可是这个设置是在上面数组里的啊?
    新定义attribute ID时,在上面两个数组里到底要不要初始化新添加的attribute ID?
  • Sorry,

    “剛看了一下源碼,zclSerializeData裡面沒有處理ZCL_DATATYPE_ARRAY,所以應該要用ZCL_DATATYPE_CHAR_STR”

    這是對的,我看的是我改過得源碼,你要用ZCL_DATATYPE_ARRAY的話必須要去修改zclSerializeData,如果不修改,建議你用用ZCL_DATATYPE_CHAR_STR

    zclxxx_Attrs[]就是讓你列出你endpoint支持的cluster跟attribute,所以你客製化的attribute要加上去,並指定他是ACCESS_CONTROL_READ, ACCESS_CONTROL_WRITE,或是ACCESS_REPORTABLE

  • 我在ZCL_CLUSTER_ID_GEN_ON_OFF下面自定义了一个attribute,看一下是否正确?
    因为是协调器和终端互发私有数据,所以协调器和终端两边都要做如下的添加是吧?
    另外发送的函数如下,帮忙看一下是否正确?
    CONST zclAttrRec_t zclSampleLight_Attrs[] =
    {
    ……
    {
    ZCL_CLUSTER_ID_GEN_ON_OFF,
    { // Attribute record
    ATTRID_ON_OFF_OFF_GENERAL,//自定义的
    ZCL_DATATYPE_UINT8,
    ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_REPORTABLE,
    (void *)&zclSampleSo_OnOff
    }
    ……
    }

    zclReportCmd_t *pReportData;
    pReportData = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
    if ( pReportData != NULL )
    {
    pReportData->numAttr = 1;
    pReportData->attrList[0].attrID = ATTRID_ON_OFF_OFF_GENERAL;
    pReportData->attrList[0].dataType = ZCL_DATATYPE_UINT8;
    pReportData->attrList[0].attrData = (void *)(&AppData);
    //数据类别
    zcl_SendReportCmd( SAMPLELIGHT_ENDPOINT, &zclSampleLight_DstAddr,
    ZCL_CLUSTER_ID_GEN_ON_OFF,
    pReportData, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, zclSampleLightSeqNum++ );
    }
    osal_mem_free( pReportData );
  • 看起來正确
  • 你好,你给的这个链接是老版协议栈的吧,添加代码后一堆错,
    我想实现的功能是,基于3.0.2,sw为协调器,light为终端,协调器组播控制终端,
    在协调器端可以把任意一个终端加到某个组里,也可以把该终端从组里删除,
    请问把终端加到某个组和从某个组删除是下面两个函数吗?
    zclGeneral_SendGroupAdd,zclGeneral_SendGroupRemove
    有没有相关的例子可以参考?
  • 那个链接是最新版CC2652R协议栈的,Z-Stack 3.0.2就是用zclGeneral_SendGroupAdd,zclGeneral_SendGroupRemove,沒有相关的例子可以参考
  • 1.添加删除组成员之前先要建立组名和组ID吧?是不是如下的代码即可?
    const char GROUP_NAME[] = { 0x08, 'm', 'y', '_', 'g', 'r', 'o', 'u', 'p' };
    #define GROUP_ID 0x0001
    2.另外有可能协调器要管理多个组,但是协调器和上位机是串口交互的,
    我是不是要在协调器里面先预设多个组名和组ID,不然通过串口也不好添加
  • 1. 代码看起來可以
    2. 可以這樣做
  • 关于启用PA的问题:
    CC2538+CC2592是在预编译里面添加一行HAL_PA_LNA_CC2592
    请问CC2530+CC2592是不是也是一样的做法?
  • 如果你的線路是參照

    ,就是在预编译里面添加一行HAL_PA_LNA_CC2592

  • 3.0.2协议栈,终端掉线的时候协议栈会自动重连,
    但是我看到下面的部分,当终端PARENT_LOST的时候会10秒后执行
    bdb_ZedAttemptRecoverNwk,这个函数和协议栈的自动重连是什么关系?
    他们是一个意思吗?
    BDB_COMMISSIONING_PARENT_LOST
    #if ZG_BUILD_ENDDEVICE_TYPE
    if ( events & SAMPLEAPP_END_DEVICE_REJOIN_EVT )
    {
    bdb_ZedAttemptRecoverNwk();
    return ( events ^ SAMPLEAPP_END_DEVICE_REJOIN_EVT );
    }
    #endif
  • BDB_COMMISSIONING_PARENT_LOST

    是你掉线后 定时器去扫一下网络,减少耗电量。
    这已经偏离了原来的主题
  • 3.0.2协议栈,终端掉线的时候协议栈会自动重连就是用你貼的這部份程式碼
  • 掉线只要DPOLL_RATE的时候才知道,如果DPOLL_RATE间隔是10秒,
    那么即使把协调器断电,终端最长需要10秒才会ZDO_STATE_CHANGE,
    此后会定期触发bdb_ZedAttemptRecoverNwk,如果不考虑终端能耗问题,
    是否可以把bdb_ZedAttemptRecoverNwk的触发改为终端一掉线立即触发,代码如下:
    #if ZG_BUILD_ENDDEVICE_TYPE
    case BDB_COMMISSIONING_PARENT_LOST:
    if(bdbCommissioningModeMsg->bdbCommissioningStatus == BDB_COMMISSIONING_NETWORK_RESTORED)
    {
    //We did recover from losing parent
    }
    else
    {
    //Parent not found, attempt to rejoin again after a fixed delay
    bdb_ZedAttemptRecoverNwk();//持续恢复网络
    }
    break;
    #endif
  • 可以這樣做,但是你掉线终端持续找尋网络一旦掉线终端很多可能會造成网络壅塞
  • 有个问题就是DPOLL_RATE在f8wConfig.cfg设定后,所有的终端都是一样的,
    这样就有一个问题,所有的终端都会在同一时间去POLL,容易造成网络拥堵,
    有没有什么办法让每个终端的DPOLL_RATE间隔是随机的,比如随机在5秒-10秒之间随机一个数,
    这样就可以避免终端较多的时候的网络拥堵问题,如果可以,请问在哪里修改代码?
  • 你終端的啟動時間是不固定的所以就算POLL_RATE间隔是固定,實際的效果出來也像是随机的,如果還是擔心可以用Zigbee 3.0的poll control cluster去改變每個終端的poll rate