找回密码
 立即注册

微信扫码登录

查看: 29|回复: 2

I find short address by zb_zdoMatchDescReq()

[复制链接]

10

主题

27

回帖

260

积分

华贵铂金

积分
260
发表于 3 天前 | 显示全部楼层 |阅读模式 来自 俄罗斯
information
说明:   建议参照本版块置顶帖内容输入必要信息
芯片型号: tlsr8258
SDK及版本: V3.7.1.4(PR)
Hello.



I have three devices.

1. Thermostat 0x535A
2. Thermostat 0xC0E0
3. Test device 0x3F13

I want to use device 3 to find all thermostats in the network, get their short addresses, so that I can read and write to the ZCL_CLUSTER_HAVC_THERMOSTAT cluster attributes.

My code, where I call test_find_hvac_cluster() on button press.


void test_find_hvac_clusterCb(void *args) {


    zdo_zdpDataInd_t *p = (zdo_zdpDataInd_t *)args;
    zdo_match_descriptor_resp_t *rsp = (zdo_match_descriptor_resp_t*)p->zpdu;

    if ((rsp->status == ZDO_SUCCESS) && (rsp->matchLen)) {
        printf("matchLen: %d\r\n", rsp->matchLen);
        printf("dstEp: %d\r\n", rsp->matchList[0]);
        printf("shortAddr: 0x%04x\r\n", rsp->nwk_addr_interest);
    }
}

void test_find_hvac_cluster() {

    zdo_match_descriptor_req_t req;

    req.nwk_addr_interest = NWK_BROADCAST_RX_ON_WHEN_IDLE;

    req.profile_id = app_simpleDesc.app_profile_id;

    req.num_in_clusters = 1;
    req.num_out_clusters = 0;
    req.cluster_list[0] = ZCL_CLUSTER_HAVC_THERMOSTAT;


    u8 sn = 0;
    zdo_status_t ret = zb_zdoMatchDescReq(NWK_BROADCAST_RX_ON_WHEN_IDLE, &req, &sn, test_find_hvac_clusterCb);
    printf("ret: %d\r\n", ret);

}




But test_find_hvac_clusterCb is called only once and reports only one thermostat 0x535A


Button push 4 time
ret: 0
matchLen: 1
dstEp: 1
shortAddr: 0x535A
Button push 4 time
ret: 0
matchLen: 1
dstEp: 1
shortAddr: 0x535A



And rsp->matchLen always returns 1.


But with the help of a sniffer you can see that both thermostats send a response.


sharex-08-11-36-960.jpg


How to do it right?

10

主题

27

回帖

260

积分

华贵铂金

积分
260
 楼主| 发表于 昨天 21:24 | 显示全部楼层 来自 俄罗斯
本帖最后由 Slacky 于 2025-8-16 21:26 编辑

Hello.


When calling a function zb_zdoMatchDescReq , function zdp_serverCmdHandler is called in zdp.c.
When two thermostats are detected, function zdp_serverCmdHandler is called twice.


_CODE_ZDO_ void zdp_serverCmdHandler(void *ind)
{
    aps_data_ind_t *p = (aps_data_ind_t *)ind;

#ifdef ZB_ROUTER_ROLE
    if (p->cluster_id == PARENT_ANNCE_RSP_CLID) {
        zdo_parentAnnounceNotify(ind);
        zb_buf_free((zb_buf_t *)ind);
        return;
    } else if (p->cluster_id == NWK_ADDR_RSP_CLID || p->cluster_id == IEEE_ADDR_RSP_CLID) {
        zdo_remoteAddrNotify(ind);
    }
#endif

    printf("shortAddr: 0x%04x, seq_num: %d\r\n", p->src_short_addr, p->asdu[0]);

    zdo_zdpDataInd_t zdpInd;
    TL_SETSTRUCTCONTENT(zdpInd, 0);

    zdpInd.src_addr = p->src_short_addr;
    zdpInd.clusterId = p->cluster_id;
    zdpInd.seq_num = p->asdu[0];
    zdpInd.status = p->asdu[1];
    zdpInd.length = p->asduLength;
    zdpInd.zpdu = p->asdu;

    zdo_zdpDataInd_t *pZdpInd = (zdo_zdpDataInd_t *)ind;
    memcpy((u8 *)pZdpInd, (u8 *)&zdpInd, sizeof(zdo_zdpDataInd_t));

    zdp_cb_process(pZdpInd->seq_num, ind);
    zb_buf_free((zb_buf_t *)ind);
}




seq_num is the same. The addresses are different, they correspond to both thermostats. But the callback function from zb_zdoMatchDescReq is called only once.

Button push 1 time
ret: 0
shortAddr: 0xC0E0
shortAddr 0x535A



It is possible that when zdp_cb_process is called for the first time, the callback function from zb_zdoMatchDescReq becomes invalid.


What to do?

10

主题

27

回帖

260

积分

华贵铂金

积分
260
 楼主| 发表于 9 小时前 | 显示全部楼层 来自 俄罗斯
I had to move zdp.c to the project and modify the code there a little. It's a pity that there are no sources from function zdp_cb_process, it would be more elegant.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Telink forum ( 沪ICP备17008231号-1 )

GMT+8, 2025-8-17 11:03 , Processed in 0.096847 second(s), 24 queries .

Powered by Telink 隐私政策

泰凌微电子版权所有 © 。保留所有权利。 2024

快速回复 返回顶部 返回列表