@@ -774,6 +774,80 @@ class XBee {
774774 Stream* _serial;
775775};
776776
777+
778+ /* *
779+ * This class can be used instead of the XBee class and allows
780+ * user-specified callback functions to be called when responses are
781+ * received, simplifying the processing code and reducing boilerplate.
782+ *
783+ * To use it, first register your callback functions using the onXxx
784+ * methods. Each method has a uintptr_t data argument, that can be used to
785+ * pass arbitrary data to the callback (useful when using the same
786+ * function for multiple callbacks, or have a generic function that can
787+ * behave differently in different circumstances). Supplying the data
788+ * parameter is optional, but the callback must always accept it (just
789+ * ignore it if it's unused). The uintptr_t type is an integer type
790+ * guaranteed to be big enough to fit a pointer (it is 16-bit on AVR,
791+ * 32-bit on ARM), so it can also be used to store a pointer to access
792+ * more data if required (using proper casts).
793+ *
794+ * There can be only one callback of each type registered at one time,
795+ * so registering callback overwrites any previously registered one. To
796+ * unregister a callback, pass NULL as the function.
797+ *
798+ * To ensure that the callbacks are actually called, call the loop()
799+ * method regularly (in your loop() function, for example). This takes
800+ * care of calling readPacket() and getResponse() other methods on the
801+ * XBee class, so there is no need to do so directly (though it should
802+ * not mess with this class if you do, it would only mean some callbacks
803+ * aren't called).
804+ */
805+ class XBeeWithCallbacks : public XBee {
806+ public:
807+
808+ /* *
809+ * Register a packet error callback. It is called whenever an
810+ * error occurs in the packet reading process. Arguments to the
811+ * callback will be the error code and the data parameter.
812+ * while registering the callback.
813+ */
814+ void onPacketError (void (*func)(uint8_t , uintptr_t ), uintptr_t data = 0) { _onPacketError.set (func, data); }
815+
816+ /* *
817+ * Register a response received callback. It is called whenever
818+ * a response was succesfully received.
819+ *
820+ * Arguments to the callback will be the received response and
821+ * the data parameter passed while registering the callback.
822+ */
823+ void onResponse (void (*func)(XBeeResponse&, uintptr_t ), uintptr_t data = 0) { _onResponse.set (func, data); }
824+
825+ /* *
826+ * Regularly call this method, which ensures that the serial
827+ * buffer is processed and the appropriate callbacks are called.
828+ */
829+ void loop ();
830+ private:
831+ template <typename Arg> struct Callback {
832+ void (*func)(Arg, uintptr_t );
833+ uintptr_t data;
834+ void set (void (*func)(Arg, uintptr_t ), uintptr_t data) {
835+ this ->func = func;
836+ this ->data = data;
837+ }
838+ bool call (Arg arg) {
839+ if (this ->func ) {
840+ this ->func (arg, this ->data );
841+ return true ;
842+ }
843+ return false ;
844+ }
845+ };
846+
847+ Callback<uint8_t > _onPacketError;
848+ Callback<XBeeResponse&> _onResponse;
849+ };
850+
777851/* *
778852 * All TX packets that support payloads extend this class
779853 */
0 commit comments