Skip to content

Add support for callbacks and various other improvements #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Aug 4, 2015

Conversation

matthijskooijman
Copy link
Contributor

This implements a number of improvements mentioned in #5. Since they turned out to be orthogonal to the changes in #6, I decided to create a new PR instead of adding these commits there.

This PR adds support for a callback-based API style, which can make sketches significantly shorter and easier to read and write. Two new examples are added that use the callback API. Another significant change is support for Zigbee Explicit TX and RX packets (e.g using a custom profile/cluster id), which allows communication with non-XBee devices (e.g. using Zigbee Home Automation). The second example uses these to scan the network for devices and supported endpoints/profiles/clusters, making it a good starting point for integrating off-the-shelf zigbee devices.

The changes to the existing getXxxResponse() API and response internal fields mentioned in #5 are not present in this PR yet, I plan to submit those later after we figure out what the best approach is there (also, I don't strictly need those changes for my book, so there is less of a hurry).

@andrewrapp, any chance you could go over this PR (and preferably also #6) in the coming weeks? If so, I'll be able to use this new API in my book, which is due early august.

This allows sending "Explicit Addressing ZigBee Command" API frames,
that allow specifying the endpoints, profile id and cluster id for a
transmitted message, e.g. to interact through standard Zigbee protocols.
This allows receiving "ZigBee Explicit Rx Indicator" API frames,
that specify the endpoints, profile id and cluster id for a
received message, e.g. to interact through standard Zigbee protocols.
These API frames are enabled by setting AO=1.
This is just a minimal implementation, that supports the onPacketError()
callback and onResponse() callback. More callbacks need to be added to
make this class truly useful.
This adds a callback for each type of response that exists. Whenever a
respons is received, the corresponding callback is called. When it is
not defined, the onOtherResponse callback is called instead.
All response classes that represent an actual API packet, now have this
constant, which should make it easier to use templates to define generic
methods that work for all response types.
This allows reusing both parts, while inserting a bit of code in
between, in subsequent commits.
This method loops until a status response is received (e.g. a
AtCommandResponse, TxResponse, etc.) to greatly simplify getting the
result of a command sent. While waiting, any other responses are
processed by the callbacks as normal, so no response gets lost while
waiting.

A matchStatus() helper method is introduced, preparing to reuse it in a
future commit.
This just combines send() and waitForStatus() in one convenient call.
This allows waiting for an arbitrary API response. Combined with a
user-defined "matching" function, this allows e.g. waiting for a reply
to a packet previously sent in a convenient way.

The main work is done using a waitForInternal() method, so the actual
waitFor() can be a template method (to allow passing a response object
directly, without having to also pass a matching API id). The
implementation could have been put inside waitFor() directly, but then
you would end up with a complete copy of the method for each response
type you wait for.
Now, if a frameId is passed, waitFor() will check for status response
while waiting. If one is received that matches the frameId and has a
non-zero status (e.g. an error), waiting stops and the status is
returned.

When sending a TX packet and subsequently listening for a RX reply, this
allows waiting for a reply and the TX status at the same time and stop
waiting if the TX turns out to have failed. This is particularly
convenient since the TX status can sometimes arrive *before* the RX
reply and sometimes *after*, which makes a sequential waitForStatus()
and waitFor() approach not work.
This allows setting both in one call, which is slightly more
convenient.
The old code didn't calculate the offsets correctly causing
isDigitalEnabled() and isDigitalOn() to only at the first sample data
(instead of looking at the mask or subsequent samples).

This introduces a getSampleStart() method to allow sharing some code
between getAnalog() and isDigitalOn().
These allow easily printing integers and XBeeAddress64 values with
leading zeroes (which Arduino's print doesn't have any easy way to do).
Also, a version is available that can print a buffer of bytes with
configurable separators.

These functions aren't used yet, but will be used in examples that will
be added next.
These functions can be used as callbacks for XBeeWithCallback and print
various packets. printErrorCb() can easily print errors to simplify
sketches. printRawResponseCb() and printResponseCb() print complete
responses and will be mostly useful for debugging (especially the
generic printResponseCb() version is fairly big due to all the strings,
it compiles to around 5.5k).
This is an example that receives packets and echoes them back to the
sender. It uses the new callbacks to show their usage.
This example allows scanning a network for joined devices, and for
endpoints, profiles and clusters supported by those devices.

At the same time, this shows some more advanced uses of the callback
API, waiting for actual reply packet received from other nodes in addition
to waiting for status replies from the local XBee module.
@matthijskooijman
Copy link
Contributor Author

I just modified the last commit, renaming the example from ZdoScan to ZdpScan. On closer reading of the Zigbee spec, turns out the discovery uses the Zigbee Device Profile, not Zigbee Device Objects.

andrewrapp added a commit that referenced this pull request Aug 4, 2015
Add support for callbacks and various other improvements
@andrewrapp andrewrapp merged commit 136c80b into andrewrapp:master Aug 4, 2015
@matthijskooijman matthijskooijman deleted the callbacks branch August 6, 2015 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants