How to Retrieve LQI for End Devices Connected via a Router in a Zigbee Network?

I am using three devices in my Zigbee network:

A Coordinator.
A Router.
An End Device.
When I retrieve the LQI data:

If both the Router and End Device connect directly to the Coordinator, I get the correct LQI values for all devices.
However, if the End Device is connected to the Coordinator via the Router (indirect connection), the LQI value for the End Device is returned as 0.


I'm using the following code to send an LQI request to the Coordinator and process the response:

 

void read_lqi_request()
{
zb_bufid_t buf = zb_buf_get_out();
zb_zdo_mgmt_lqi_param_t *req_param = ZB_BUF_GET_PARAM(buf, zb_zdo_mgmt_lqi_param_t);

req_param->start_index = 0;
req_param->dst_addr = 0x00; // Coordinator's short address

zb_uint8_t tsn = zb_zdo_mgmt_lqi_req(buf, get_lqi_cb);

if (tsn == RET_OK)
{
TRACE_MSG(TRACE_APS1, "LQI request sent successfully", (FMT__0));
}
else
{
TRACE_MSG(TRACE_ERROR, "Failed to send LQI request", (FMT__0));
}
}

void get_lqi_cb(zb_uint8_t param)
{
zb_bufid_t buf = param;
zb_uint8_t *zdp_cmd = zb_buf_begin(buf);
zb_zdo_mgmt_lqi_resp_t *resp = (zb_zdo_mgmt_lqi_resp_t *)(zdp_cmd);
zb_zdo_neighbor_table_record_t *record = (zb_zdo_neighbor_table_record_t *)(resp + 1);
zb_uint_t i;

printf("LQI Callback: status=%d, neighbor_table_entries=%d, start_index=%d, neighbor_table_list_count=%d\n",
resp->status, resp->neighbor_table_entries, resp->start_index, resp->neighbor_table_list_count);

for (i = 0; i < resp->neighbor_table_list_count; i++)
{
printf("Network Addr=%d, Dev Type=%d, RxOnWhenIdle=%d, Relationship=%d, PermitJoin=%d, Depth=%d, LQI=%d\n",
record->network_addr,
ZB_ZDO_RECORD_GET_DEVICE_TYPE(record->type_flags),
ZB_ZDO_RECORD_GET_RX_ON_WHEN_IDLE(record->type_flags),
ZB_ZDO_RECORD_GET_RELATIONSHIP(record->type_flags),
record->permit_join, record->depth, record->lqi);

record++;
}
}

Parents Reply Children
  • So from your coordinator's application, you should do something like:

    void read_lqi_request()
    {
    zb_bufid_t buf = zb_buf_get_out();
    zb_zdo_mgmt_lqi_param_t *req_param = ZB_BUF_GET_PARAM(buf, zb_zdo_mgmt_lqi_param_t);
    
    req_param->start_index = 0;
    req_param->dst_addr = <ADDRESS>; // End device's short address. <--- This line
    
    zb_uint8_t tsn = zb_zdo_mgmt_lqi_req(buf, get_lqi_cb);
    
    if (tsn == RET_OK)
    {
    TRACE_MSG(TRACE_APS1, "LQI request sent successfully", (FMT__0));
    }
    else
    {
    TRACE_MSG(TRACE_ERROR, "Failed to send LQI request", (FMT__0));
    }
    }
    
    void get_lqi_cb(zb_uint8_t param)
    {
    zb_bufid_t buf = param;
    zb_uint8_t *zdp_cmd = zb_buf_begin(buf);
    zb_zdo_mgmt_lqi_resp_t *resp = (zb_zdo_mgmt_lqi_resp_t *)(zdp_cmd);
    zb_zdo_neighbor_table_record_t *record = (zb_zdo_neighbor_table_record_t *)(resp + 1);
    zb_uint_t i;
    
    printf("LQI Callback: status=%d, neighbor_table_entries=%d, start_index=%d, neighbor_table_list_count=%d\n",
    resp->status, resp->neighbor_table_entries, resp->start_index, resp->neighbor_table_list_count);
    
    for (i = 0; i < resp->neighbor_table_list_count; i++)
    {
    printf("Network Addr=%d, Dev Type=%d, RxOnWhenIdle=%d, Relationship=%d, PermitJoin=%d, Depth=%d, LQI=%d\n",
    record->network_addr,
    ZB_ZDO_RECORD_GET_DEVICE_TYPE(record->type_flags),
    ZB_ZDO_RECORD_GET_RX_ON_WHEN_IDLE(record->type_flags),
    ZB_ZDO_RECORD_GET_RELATIONSHIP(record->type_flags),
    record->permit_join, record->depth, record->lqi);
    
    record++;
    }
    }

    It is your own implementation, but you need to call it from the coordinator, and use the end device's address as the destination address.

    Best regards,

    Edvin

Related