Home/Support/Support Forum/How to use built-in xbee programmable ZDO/ZCL support

How to use built-in xbee programmable ZDO/ZCL support

0 votes
I had similar questions to what was asked here. I am finding bits and pieces of documentation like:

http://xbee-sdk-doc.readthedocs.org/en/1.5.7/api_doc/

http://exsilium.github.io/xbee-sdk-doc/group__zcl__time.html

http://ftp1.digi.com/support/images/APP_NOTE_XBee_ZigBee_Device_Profile.pdf

that all give me a hint that there's some ZDO/ZCL support that I don't know how to use. For basic ZCL attributes, it seems like I can set up a table of objects and just have my code update the values, and then underlying software will handle things like ZDO requests (read, write, subscriptions, etc.).

I can't really find examples of how that's done, though.
asked Apr 10, 2015 in XBee Programmable Development by wz2b New to the Community (36 points)

Please log in or register to answer this question.

6 Answers

0 votes
 
Best answer
Suppose you set up a callback for a certain endpoint or cluster, like this:
Code:
const wpan_cluster_table_entry_t custom_ep_clusters[] = { { 0x40, cluster_40_handler, NULL, WPAN_CLUST_FLAG_INOUT }, WPAN_CLUST_ENTRY_LIST_END };

When the callback gets called, does the normal response generation still work if it's a standard ZDO request like "read attribute"? Or am I responsible for generating the response?
answered Apr 19, 2015 by wz2b New to the Community (36 points)
selected Apr 19, 2015 by wz2b
#define ZCL_CLUST_ENTRY_IDENTIFY_SERVER
    { ZCL_CLUST_IDENTIFY,
        &zcl_identify_command,
        zcl_identify_attribute_tree,
        WPAN_CLUST_FLAG_SERVER }

Where you have NULL is the attribute tree that defines your attribute. With that in place you wouldn't need the custom handler unless, like the Identify cluster, you are adding additional custom commands. All of the attributes are automatically handled as specified in the attribute tree.

Take a look at how the attribute tree is defined for the Identify cluster and you should be able to piece together how to do something similar for your use-case.
0 votes
That is because the functions you are referring to are external to the radio and need to exist within your application. Your best source for that is www.zigbee.org
answered Apr 10, 2015 by mvut Veteran of the Digi Community (11,302 points)
Oh, I see.  Aren't these functions in the XBee Programmable API?  For example, the API has a file zcl_time.c which has a Digi International copyright notice on it ... inside that are methods like zcl_time_set().  I'm just trying to figure out how to use them ....
0 votes
The Basic and Identify cluster examples might be a little simpler or more straightforward to use as a reference.

The ZDO/ZCL support is powerful enough that you can implement whatever custom attribute/command/cluster/endpoint functionality you need but can get a little involved.

Is there a specific problem you're trying to solve?
answered Apr 12, 2015 by jlovinger Veteran of the Digi Community (421 points)
edited Apr 12, 2015 by jlovinger
0 votes
Sure, I can explain. I bought one of these:

Rainwise Tipping Bucket

and put an Xbee ZB Programmable inside the waterproof cylinder inside. I wrote a small, simple program to count pulses (and debounce them in software). To send data, I've taken a few liberties with ZDO and ZCL -mainly that I'm using a Report Attributes command but with no subscription requirement. There's an implied "subscription" that changes should be sent as a Report Attribute to the coordinator.

To formulate the messages I built a little ZCL message builder library. It works like this:
Code:
void send() { int rc; int add_result; init_assembly_buffer(&asy, buf, sizeof(buf)); add_zcl_header_with_mfg(&asy, 0, /* frame control */ 0xBEEF, /* manufacturer id */ seq++, ZCL_CMD_REPORT_ATTRIB); /* ADD AS MANY OF THESE AS WE WANT ATTRS IN THIS MESSAGE */ add_result = add_zcl_attribute_float(&asy, 5, 123.4f); if(add_result == SIMPLE_ZCL_OK) { printf("Add float OK\n"); } /* * Fill in the envelope */ wpan_envelope_create(&envelope, &xdev.wpan_dev, WPAN_IEEE_ADDR_COORDINATOR, WPAN_NET_ADDR_UNDEFINED); envelope.options = 0x00; envelope.cluster_id = 0x9999; envelope.profile_id = 0xAAAA; envelope.dest_endpoint = 0x40; envelope.source_endpoint = 0x40; envelope.payload = buf; envelope.length = zcl_builder_buflen(&asy); rc = wpan_envelope_send(&envelope); printf("send wpan_envelope_send() returned %d\n", rc); }

So to answer your question: I have the feeling I shouldn't have to do any of this ... because the XBAee Programmable libraries will just let me declare that I have these attributes, and then the normal read/write/subscribe ZDO commands will just work.

is that true?
answered Apr 12, 2015 by wz2b New to the Community (36 points)
The declaration can be complicated.

You need to build up a structure going all the way from your attribute definition (with a callback to return its read value), to a list of attributes for your custom cluster, the cluster itself containing your attributes, the endpoint containing your cluster, and finally the overall endpoint structure for your node.

The best example to work from in the given source code for your case is likely identify.c/h.

Does a little more than you need (custom commands in addition to custom attribute) but it has a single attribute with read callback. Check out ZCL_CLUST_ENTRY_IDENTIFY_SERVER and zcl_identify_attribute_tree for your primary hooks in.

I'd recommend trying to integrate the identify server into your code, make sure you can read its attribute then morph it into something that fits with your specific needs. Change attribute type, callbacks, etc.
0 votes
Cool.

What happens if someone tries to use a command not supported by the SDK ZCL/ZDO layer? For example:
Code:
#define ZCL_CMD_CONFIGURE_REPORT 0x06

It looks like in zigbee_zcl.c in this function:
Code:
zigbee_zcl_debug int zcl_general_command( const wpan_envelope_t FAR *envelope, void FAR *context)

that it falls through to:
Code:
return zcl_invalid_command( envelope);

Is it possible to have your callback handle this? Or, if I want to use subscriptions (reporting) would it be better to just have my callback handle everything?
answered Apr 19, 2015 by wz2b New to the Community (36 points)
I don't believe the library comes with support for reporting. However, you can definitely add your own support especially if only for a limited subset of the functionality to make life simpler.

Refer to the zcl_identify_command() function that is provided for the Identify cluster I've been referencing so far. That shows a custom handler to peel off and handle certain commands. Any commands that aren't processed it then passes into the default zcl_general_command() function.

So define something similar to catch and process reporting commands and add it to your cluster definition.
0 votes
It is true that Digi does not provide examples nor good documentation when it comes to ZigBee ZDO/ZCL support. I suspect this could be a licensing related issue as ZigBee specification is provided publicly only for non-commercial purposes. In any case wanted to add an example to get ZDO support working in the Programmable XBee using the built in ZDO code. Hope this is of help to someone.

By default if your AO parameter is either 0 or 1, the XBee radio firmware will respond to the ZDO requests. The easiest to try this out is by sending "Active Endpoints Request" (Cluster ID 0x0005) to the module. The module will respond with E8 (Digi Endpoint) and E6 (Digi Command) being available. When AO is set to 3 or if you have one of the following defined in your project:
Code:
- ENABLE_XBEE_HANDLE_RX - ENABLE_OTA_UPDATE - ENABLE_XBEE_HANDLE_ND_RESPONSE_FRAMES

or directly <code>ENABLE_XBEE_HANDLE_RX_ZCL_FRAMES</code> which sets AO=3 at boot, you will notice that you will not receive any reply for the ZDO Active Endpoints Request - because by default ZDO endpoint is not added to active list. To do so, you need to:

1. Create a global for ZDO transaction tracking.
Code:
wpan_ep_state_t zdo_ep_state;

2. Add the ZDO endpoint to the list in custom.h (based on xbee_custom_endpoint example):
Code:
#include <zigbee/zdo.h> extern wpan_ep_state_t zdo_ep_state; #define CUSTOM_ENDPOINT 0x13 #define CUSTOM_EP_PROFILE 0x5EBA #define EP_INCLUDE_DECLARATIONS extern const wpan_cluster_table_entry_t custom_ep_clusters[]; int custom_ep_default_cluster(const wpan_envelope_t FAR *, void FAR *); #define ADDITIONAL_ENDPOINTS {CUSTOM_ENDPOINT, CUSTOM_EP_PROFILE, custom_ep_default_cluster, NULL, 0x0000, 0x00, custom_ep_clusters}, \ ZDO_ENDPOINT(zdo_ep_state)

If you resend the "Active Endpoints Request" you'll notice that E8 (Digi Endpoint) and 13 (your custom endpoint) will be sent back in the reply.
answered Oct 3, 2016 by exile Community Contributor (92 points)
edited Oct 3, 2016 by exile
...