This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Get received APS data from Zigbee stack

We have a Zigbee device that doesn't seem to use ZCL to transfer data and I have been trying to see if there is a way to get it working with an nrf52840 acting as a coordinator. The device successfully authenticates and starts sending data that I can see using Wireshark. Wireshark complains about the ZCL data and when I look at that part of the packet I can tell it is actually the specially encoded data coming from the device and doesn't look like it fits the ZCL specification at all. I think if I could just access the APS data directly that would be all I need since the device encoding is already something we handle with other coordinators. Is there a way to access the incoming APS data directly?

The following is an example packet capture from Wireshark showing the data in question:

0000 61 88 27 21 74 00 00 1c 4c 48 00 00 00 1c 4c 0a a.'!t...LH....L.
0010 15 00 01 01 00 01 00 01 1e 00 02 39 08 4e 56 00 ...........9.NV.
0020 41 41 41 41 41 30 90 2d 02 09 26 0c 0a 02 15 1c AAAAA0.-..&.....
0030 4c 24 23 23 01 00 00 00 04 21 74 1a 00 00 fc d1 L$##.....!t.....
0040 01 0c f3 0d 00 00 44 08 00 00 00 00 00 00 20 05 ......D....... .
0050 47 68 6f 73 74 Ghost

The device always uses endpoint 1, cluster 1, profile 1. What should be the ZCL frame is specially encoded data from the device.

  • Hi,

    I got the Zigbee team to look at the screenshot of the sniffer log. It is not ZCL that's the problem, but the profile ID (0x0001), which is not recognized by the stack. In such situations, the only solution is to use the zb_af_set_data_indication API.

    Please register the callback before zboss_start:

    ...
    zb_af_set_data_indication(data_indication);
    ...

    Example callback implementation:

    static zb_uint8_t data_indication(zb_uint8_t param)
    {
      zb_buf_t *buf = ZB_BUF_FROM_REF(param);
      zb_uint8_t aps_payload_size = 0;
      zb_uint8_t *aps_payload_ptr = zb_aps_get_aps_payload(param, &aps_payload_size);
      zb_apsde_data_indication_t *data_ind = ZB_GET_BUF_PARAM(buf, zb_apsde_data_indication_t);
      zb_bool_t processed = ZB_FALSE;
      if ((data_ind->profileid == 0x0001) &&
          (data_ind->clusterid == 0x0001))
      {
        NRF_LOG_DEBUG("zb_buf_len: %hd, aps_payload_size: %hd",
                      ZB_BUF_LEN(buf), aps_payload_size));
        for (zb_uint8_t i = 0; i < aps_payload_size; ++i)
        {
          NRF_LOG_DEBUG("aps_payload[%hd] == 0x%hx",
                        i, aps_payload_ptr[i]));
        }
        ZB_FREE_BUF(buf);
        processed = ZB_TRUE;
      }
      return processed;
    }

    Best regards,

    Marte

  • I've tried this a number of different ways with no luck. First off I attempted to use the above call in both NCS v1.5.0 and nRF5 SDK for Thread and Zigbee v4.1.0, it isn't clear if one of those should be used over the other.

    First I'll say that the code you gave doesn't compile because it references calls that don't exist in either SDK so I'm questioning if I'm trying to use the right SDKs. Is this internal code for zboss that isn't available or is it part of a different SDK that I need to download?

    Given that the example code doesn't compile I replaced it with the following just to test that I could see some output when the callback is called:

    static zb_uint8_t data_indication(zb_uint8_t param)
    {
      NRF_LOG_ERROR("**** data_indication called");
    
      return ZB_FALSE;
    }

    I modified the Zigbee CLI example code in thenRF5 SDK for Thread and Zigbee v4.1.0 source by adding a new command that simply calls zb_af_set_data_indication(data_indication); as follows:

    static void cmd_app_stuff(nrf_cli_t const * p_cli, size_t argc, char **argv)
    {
      nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Setting data indication.\n");
      zb_af_set_data_indication(data_indication);
    }
    
    NRF_CLI_CMD_REGISTER(set_di, NULL, "Set data indication", cmd_app_stuff);

    I also set the ZIGBEE_TRACE_MASK setting to TRACE_SUBSYSTEM_NWK to see if that would show the interaction. I used the following set of commands to configure the Zigbee CLI example once running:

    log enable info app
    log enable info zboss
    log go
    
    bdb channel 26
    bdb nwkkey 0xanetworkkey
    bdb extpanid 0xapanid
    bdb role zc
    set_di
    bdb start
    bdb legacy enable

    The end device connects and authorizes but the data_indication is never called:

    <info> zboss: DE AD 0A 02 B2 A5 36 00|......6.
    <info> zboss: 26 01 A5 05 DE AD 0E 02|&.......
    <info> zboss: B4 A5 37 00 2B 01 05 01|..7.+...
    <info> zboss: 0F 00 00 00 DE AD 0A 02|........
    <info> zboss: B4 A5 38 00 2B 01 18 01|..8.+...
    <info> zboss: DE AD 1A 02 D7 A5 39 00|......9.
    <info> zboss: 3E 01 66 01 A8 07 00 00|>.f.....
    <info> zboss: A8 07 00 00 4E 56 00 41|....NV.A
    <info> app: Device update received (short: 0x07A8, long: 564d52544100564e, status: 3)
    <info> app: Device authorization event received (short: 0x07A8, long: 564d5254, authorization type: 0, authorization status: 0)
    >

    The data_indication callback is never called. I can see from the wireshark trace that the end device sends the data right after the authorization but I don't see anything more from the CLI until other devices authorize.

    Is there something more specific that needs to be done to enable this callback?

Related