/** * Copyright (c) 2009 Andrew Rapp. All rights reserved. * * This file is part of XBee-Arduino. * * XBee-Arduino is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * XBee-Arduino is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with XBee-Arduino. If not, see . */ #ifndef XBee_h #define XBee_h #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif #include #define SERIES_1 #define SERIES_2 #define SERIES_DIGIMESH // set to ATAP value of XBee. AP=2 is recommended #define ATAP 2 #define START_BYTE 0x7e #define ESCAPE 0x7d #define XON 0x11 #define XOFF 0x13 // This value determines the size of the byte array for receiving RX packets // Most users won't be dealing with packets this large so you can adjust this // value to reduce memory consumption. But, remember that // if a RX packet exceeds this size, it cannot be parsed! // This value is determined by the largest packet size (100 byte payload + 64-bit address + option byte and rssi byte) of a series 1 radio #define MAX_FRAME_DATA_SIZE 110 #define BROADCAST_ADDRESS 0xffff #define ZB_BROADCAST_ADDRESS 0xfffe // the non-variable length of the frame data (not including frame id or api id or variable data size (e.g. payload, at command set value) #define ZB_TX_API_LENGTH 12 #define DM_TX_API_LENGTH 12 #define TX_16_API_LENGTH 3 #define TX_64_API_LENGTH 9 #define AT_COMMAND_API_LENGTH 2 #define REMOTE_AT_COMMAND_API_LENGTH 13 // start/length(2)/api/frameid/checksum bytes #define PACKET_OVERHEAD_LENGTH 6 // api is always the third byte in packet #define API_ID_INDEX 3 // frame position of rssi byte #define RX_16_RSSI_OFFSET 2 #define RX_64_RSSI_OFFSET 8 #define DEFAULT_FRAME_ID 1 #define NO_RESPONSE_FRAME_ID 0 // TODO put in tx16 class #define ACK_OPTION 0 #define DISABLE_ACK_OPTION 1 #define BROADCAST_OPTION 4 // RX options #define ZB_PACKET_ACKNOWLEDGED 0x01 #define ZB_BROADCAST_PACKET 0x02 #define DM_PACKET_ACKNOWLEDGED 0x01 #define DM_BROADCAST_PACKET 0x02 // not everything is implemented! /** * Api Id constants */ #define TX_64_REQUEST 0x0 #define TX_16_REQUEST 0x1 #define DM_TX_REQUEST 0x10 #define AT_COMMAND_REQUEST 0x08 #define AT_COMMAND_QUEUE_REQUEST 0x09 #define REMOTE_AT_REQUEST 0x17 #define DM_REMOTE_AT_REQUEST 0x19 #define ZB_TX_REQUEST 0x10 #define ZB_EXPLICIT_TX_REQUEST 0x11 #define RX_64_RESPONSE 0x80 #define RX_16_RESPONSE 0x81 #define RX_64_IO_RESPONSE 0x82 #define RX_16_IO_RESPONSE 0x83 #define DM_RX_RESPONSE 0X90 #define AT_RESPONSE 0x88 #define TX_STATUS_RESPONSE 0x89 #define DM_TX_STATUS_RESPONSE 0x8b #define MODEM_STATUS_RESPONSE 0x8a #define ZB_RX_RESPONSE 0x90 #define ZB_EXPLICIT_RX_RESPONSE 0x91 #define DM_EXPLICIT_RX_RESPONSE 0x91 #define ZB_TX_STATUS_RESPONSE 0x8b #define ZB_IO_SAMPLE_RESPONSE 0x92 #define ZB_IO_NODE_IDENTIFIER_RESPONSE 0x95 #define DM_IO_NODE_IDENTIFIER_RESPONSE 0x95 #define AT_COMMAND_RESPONSE 0x88 #define REMOTE_AT_COMMAND_RESPONSE 0x97 /** * TX STATUS constants */ #define SUCCESS 0x0 #define CCA_FAILURE 0x2 #define INVALID_DESTINATION_ENDPOINT_SUCCESS 0x15 #define NETWORK_ACK_FAILURE 0x21 #define NOT_JOINED_TO_NETWORK 0x22 #define SELF_ADDRESSED 0x23 #define ADDRESS_NOT_FOUND 0x24 #define ROUTE_NOT_FOUND 0x25 #define PAYLOAD_TOO_LARGE 0x74 // modem status #define HARDWARE_RESET 0 #define WATCHDOG_TIMER_RESET 1 #define ASSOCIATED 2 #define DISASSOCIATED 3 #define SYNCHRONIZATION_LOST 4 #define COORDINATOR_REALIGNMENT 5 #define COORDINATOR_STARTED 6 #define ZB_BROADCAST_RADIUS_MAX_HOPS 0 #define DM_BROADCAST_RADIUS_MAX_HOPS 0 #define ZB_TX_UNICAST 0 #define ZB_TX_BROADCAST 8 #define DM_TX_BROADCAST 8 #define AT_OK 0 #define AT_ERROR 1 #define AT_INVALID_COMMAND 2 #define AT_INVALID_PARAMETER 3 #define AT_NO_RESPONSE 4 #define NO_ERROR 0 #define CHECKSUM_FAILURE 1 #define PACKET_EXCEEDS_BYTE_ARRAY_LENGTH 2 #define UNEXPECTED_START_BYTE 3 /** * The super class of all XBee responses (RX packets) * Users should never attempt to create an instance of this class; instead * create an instance of a subclass * It is recommend to reuse subclasses to conserve memory */ class XBeeResponse { public: //static const int MODEM_STATUS = 0x8a; /** * Default constructor */ XBeeResponse(); /** * Returns Api Id of the response */ uint8_t getApiId(); void setApiId(uint8_t apiId); /** * Returns the MSB length of the packet */ uint8_t getMsbLength(); void setMsbLength(uint8_t msbLength); /** * Returns the LSB length of the packet */ uint8_t getLsbLength(); void setLsbLength(uint8_t lsbLength); /** * Returns the packet checksum */ uint8_t getChecksum(); void setChecksum(uint8_t checksum); /** * Returns the length of the frame data: all bytes after the api id, and prior to the checksum * Note up to release 0.1.2, this was incorrectly including the checksum in the length. */ uint8_t getFrameDataLength(); void setFrameData(uint8_t* frameDataPtr); /** * Returns the buffer that contains the response. * Starts with byte that follows API ID and includes all bytes prior to the checksum * Length is specified by getFrameDataLength() * Note: Unlike Digi's definition of the frame data, this does not start with the API ID.. * The reason for this is all responses include an API ID, whereas my frame data * includes only the API specific data. */ uint8_t* getFrameData(); void setFrameLength(uint8_t frameLength); // to support future 65535 byte packets I guess /** * Returns the length of the packet */ uint16_t getPacketLength(); /** * Resets the response to default values */ void reset(); /** * Initializes the response */ void init(); #ifdef SERIES_2 /** * Call with instance of ZBTxStatusResponse class only if getApiId() == ZB_TX_STATUS_RESPONSE * to populate response */ void getZBTxStatusResponse(XBeeResponse &response); /** * Call with instance of ZBRxResponse class only if getApiId() == ZB_RX_RESPONSE * to populate response */ void getZBRxResponse(XBeeResponse &response); /** * Call with instance of ZBRxIoSampleResponse class only if getApiId() == ZB_IO_SAMPLE_RESPONSE * to populate response */ void getZBRxIoSampleResponse(XBeeResponse &response); #endif #ifdef SERIES_1 /** * Call with instance of TxStatusResponse only if getApiId() == TX_STATUS_RESPONSE */ void getTxStatusResponse(XBeeResponse &response); /** * Call with instance of Rx16Response only if getApiId() == RX_16_RESPONSE */ void getRx16Response(XBeeResponse &response); /** * Call with instance of Rx64Response only if getApiId() == RX_64_RESPONSE */ void getRx64Response(XBeeResponse &response); /** * Call with instance of Rx16IoSampleResponse only if getApiId() == RX_16_IO_RESPONSE */ void getRx16IoSampleResponse(XBeeResponse &response); /** * Call with instance of Rx64IoSampleResponse only if getApiId() == RX_64_IO_RESPONSE */ void getRx64IoSampleResponse(XBeeResponse &response); #endif #ifdef SERIES_DIGIMESH /** * Call with instance of DMTxStatusResponse class only if getApiId() == DM_TX_STATUS_RESPONSE * to populate response */ // fatto! void getDMTxStatusResponse(XBeeResponse &response); /** * Call with instance of DMRxResponse class only if getApiId() == DM_RX_RESPONSE * to populate response */ // fatto! void getDMRxResponse(XBeeResponse &response); #endif /** * Call with instance of AtCommandResponse only if getApiId() == AT_COMMAND_RESPONSE */ void getAtCommandResponse(XBeeResponse &responses); /** * Call with instance of RemoteAtCommandResponse only if getApiId() == REMOTE_AT_COMMAND_RESPONSE */ void getRemoteAtCommandResponse(XBeeResponse &response); /** * Call with instance of ModemStatusResponse only if getApiId() == MODEM_STATUS_RESPONSE */ void getModemStatusResponse(XBeeResponse &response); /** * Returns true if the response has been successfully parsed and is complete and ready for use */ bool isAvailable(); void setAvailable(bool complete); /** * Returns true if the response contains errors */ bool isError(); /** * Returns an error code, or zero, if successful. * Error codes include: CHECKSUM_FAILURE, PACKET_EXCEEDS_BYTE_ARRAY_LENGTH, UNEXPECTED_START_BYTE */ uint8_t getErrorCode(); void setErrorCode(uint8_t errorCode); protected: // pointer to frameData uint8_t* _frameDataPtr; private: void setCommon(XBeeResponse &target); uint8_t _apiId; uint8_t _msbLength; uint8_t _lsbLength; uint8_t _checksum; uint8_t _frameLength; bool _complete; uint8_t _errorCode; }; class XBeeAddress { public: XBeeAddress(); }; /** * Represents a 64-bit XBee Address */ class XBeeAddress64 : public XBeeAddress { public: XBeeAddress64(uint32_t msb, uint32_t lsb); XBeeAddress64(); uint32_t getMsb(); uint32_t getLsb(); void setMsb(uint32_t msb); void setLsb(uint32_t lsb); private: uint32_t _msb; uint32_t _lsb; }; /** * This class is extended by all Responses that include a frame id */ class FrameIdResponse : public XBeeResponse { public: FrameIdResponse(); uint8_t getFrameId(); private: uint8_t _frameId; }; /** * Common functionality for both Series 1 and 2 data RX data packets */ class RxDataResponse : public XBeeResponse { public: RxDataResponse(); /** * Returns the specified index of the payload. The index may be 0 to getDataLength() - 1 * This method is deprecated; use uint8_t* getData() */ uint8_t getData(int index); /** * Returns the payload array. This may be accessed from index 0 to getDataLength() - 1 */ uint8_t* getData(); /** * Returns the length of the payload */ virtual uint8_t getDataLength() = 0; /** * Returns the position in the frame data where the data begins */ virtual uint8_t getDataOffset() = 0; }; // getResponse to return the proper subclass: // we maintain a pointer to each type of response, when a response is parsed, it is allocated only if NULL // can we allocate an object in a function? #ifdef SERIES_2 /** * Represents a Series 2 TX status packet */ class ZBTxStatusResponse : public FrameIdResponse { public: ZBTxStatusResponse(); uint16_t getRemoteAddress(); uint8_t getTxRetryCount(); uint8_t getDeliveryStatus(); uint8_t getDiscoveryStatus(); bool isSuccess(); }; /** * Represents a Series 2 RX packet */ class ZBRxResponse : public RxDataResponse { public: ZBRxResponse(); XBeeAddress64& getRemoteAddress64(); uint16_t getRemoteAddress16(); uint8_t getOption(); uint8_t getDataLength(); // frame position where data starts uint8_t getDataOffset(); private: XBeeAddress64 _remoteAddress64; }; /** * Represents a Series 2 RX I/O Sample packet */ class ZBRxIoSampleResponse : public ZBRxResponse { public: ZBRxIoSampleResponse(); bool containsAnalog(); bool containsDigital(); /** * Returns true if the pin is enabled */ bool isAnalogEnabled(uint8_t pin); /** * Returns true if the pin is enabled */ bool isDigitalEnabled(uint8_t pin); /** * Returns the 10-bit analog reading of the specified pin. * Valid pins include ADC:xxx. */ uint16_t getAnalog(uint8_t pin); /** * Returns true if the specified pin is high/on. * Valid pins include DIO:xxx. */ bool isDigitalOn(uint8_t pin); uint8_t getDigitalMaskMsb(); uint8_t getDigitalMaskLsb(); uint8_t getAnalogMask(); }; #endif #ifdef SERIES_DIGIMESH /** * Represents a Series DM TX status packet */ // fatto! class DMTxStatusResponse : public FrameIdResponse { public: DMTxStatusResponse(); uint8_t getTxRetryCount(); uint8_t getDeliveryStatus(); uint8_t getDiscoveryStatus(); bool isSuccess(); }; /** * Represents a Series DM RX packet */ // fatto! class DMRxResponse : public RxDataResponse { public: DMRxResponse(); XBeeAddress64& getRemoteAddress64(); uint8_t getOption(); uint8_t getDataLength(); // frame position where data starts uint8_t getDataOffset(); private: XBeeAddress64 _remoteAddress64; }; #endif #ifdef SERIES_1 /** * Represents a Series 1 TX Status packet */ class TxStatusResponse : public FrameIdResponse { public: TxStatusResponse(); uint8_t getStatus(); bool isSuccess(); }; /** * Represents a Series 1 RX packet */ class RxResponse : public RxDataResponse { public: RxResponse(); // remember rssi is negative but this is unsigned byte so it's up to you to convert uint8_t getRssi(); uint8_t getOption(); bool isAddressBroadcast(); bool isPanBroadcast(); uint8_t getDataLength(); uint8_t getDataOffset(); virtual uint8_t getRssiOffset() = 0; }; /** * Represents a Series 1 16-bit address RX packet */ class Rx16Response : public RxResponse { public: Rx16Response(); uint8_t getRssiOffset(); uint16_t getRemoteAddress16(); protected: uint16_t _remoteAddress; }; /** * Represents a Series 1 64-bit address RX packet */ class Rx64Response : public RxResponse { public: Rx64Response(); uint8_t getRssiOffset(); XBeeAddress64& getRemoteAddress64(); private: XBeeAddress64 _remoteAddress; }; /** * Represents a Series 1 RX I/O Sample packet */ class RxIoSampleBaseResponse : public RxResponse { public: RxIoSampleBaseResponse(); /** * Returns the number of samples in this packet */ uint8_t getSampleSize(); bool containsAnalog(); bool containsDigital(); /** * Returns true if the specified analog pin is enabled */ bool isAnalogEnabled(uint8_t pin); /** * Returns true if the specified digital pin is enabled */ bool isDigitalEnabled(uint8_t pin); /** * Returns the 10-bit analog reading of the specified pin. * Valid pins include ADC:0-5. Sample index starts at 0 */ uint16_t getAnalog(uint8_t pin, uint8_t sample); /** * Returns true if the specified pin is high/on. * Valid pins include DIO:0-8. Sample index starts at 0 */ bool isDigitalOn(uint8_t pin, uint8_t sample); uint8_t getSampleOffset(); private: }; class Rx16IoSampleResponse : public RxIoSampleBaseResponse { public: Rx16IoSampleResponse(); uint16_t getRemoteAddress16(); uint8_t getRssiOffset(); }; class Rx64IoSampleResponse : public RxIoSampleBaseResponse { public: Rx64IoSampleResponse(); XBeeAddress64& getRemoteAddress64(); uint8_t getRssiOffset(); private: XBeeAddress64 _remoteAddress; }; #endif /** * Represents a Modem Status RX packet */ class ModemStatusResponse : public XBeeResponse { public: ModemStatusResponse(); uint8_t getStatus(); }; /** * Represents an AT Command RX packet */ class AtCommandResponse : public FrameIdResponse { public: AtCommandResponse(); /** * Returns an array containing the two character command */ uint8_t* getCommand(); /** * Returns the command status code. * Zero represents a successful command */ uint8_t getStatus(); /** * Returns an array containing the command value. * This is only applicable to query commands. */ uint8_t* getValue(); /** * Returns the length of the command value array. */ uint8_t getValueLength(); /** * Returns true if status equals AT_OK */ bool isOk(); }; /** * Represents a Remote AT Command RX packet */ class RemoteAtCommandResponse : public AtCommandResponse { public: RemoteAtCommandResponse(); /** * Returns an array containing the two character command */ uint8_t* getCommand(); /** * Returns the command status code. * Zero represents a successful command */ uint8_t getStatus(); /** * Returns an array containing the command value. * This is only applicable to query commands. */ uint8_t* getValue(); /** * Returns the length of the command value array. */ uint8_t getValueLength(); /** * Returns the 16-bit address of the remote radio */ uint16_t getRemoteAddress16(); /** * Returns the 64-bit address of the remote radio */ XBeeAddress64& getRemoteAddress64(); /** * Returns true if command was successful */ bool isOk(); private: XBeeAddress64 _remoteAddress64; }; /** * Super class of all XBee requests (TX packets) * Users should never create an instance of this class; instead use an subclass of this class * It is recommended to reuse Subclasses of the class to conserve memory *

* This class allocates a buffer to */ class XBeeRequest { public: /** * Constructor * TODO make protected */ XBeeRequest(uint8_t apiId, uint8_t frameId); /** * Sets the frame id. Must be between 1 and 255 inclusive to get a TX status response. */ void setFrameId(uint8_t frameId); /** * Returns the frame id */ uint8_t getFrameId(); /** * Returns the API id */ uint8_t getApiId(); // setting = 0 makes this a pure virtual function, meaning the subclass must implement, like abstract in java /** * Starting after the frame id (pos = 0) and up to but not including the checksum * Note: Unlike Digi's definition of the frame data, this does not start with the API ID. * The reason for this is the API ID and Frame ID are common to all requests, whereas my definition of * frame data is only the API specific data. */ virtual uint8_t getFrameData(uint8_t pos) = 0; /** * Returns the size of the api frame (not including frame id or api id or checksum). */ virtual uint8_t getFrameDataLength() = 0; //void reset(); protected: void setApiId(uint8_t apiId); private: uint8_t _apiId; uint8_t _frameId; }; // TODO add reset/clear method since responses are often reused /** * Primary interface for communicating with an XBee Radio. * This class provides methods for sending and receiving packets with an XBee radio via the serial port. * The XBee radio must be configured in API (packet) mode (AP=2) * in order to use this software. *

* Since this code is designed to run on a microcontroller, with only one thread, you are responsible for reading the * data off the serial buffer in a timely manner. This involves a call to a variant of readPacket(...). * If your serial port is receiving data faster than you are reading, you can expect to lose packets. * Arduino only has a 128 byte serial buffer so it can easily overflow if two or more packets arrive * without a call to readPacket(...) *

* In order to conserve resources, this class only supports storing one response packet in memory at a time. * This means that you must fully consume the packet prior to calling readPacket(...), because calling * readPacket(...) overwrites the previous response. *

* This class creates an array of size MAX_FRAME_DATA_SIZE for storing the response packet. You may want * to adjust this value to conserve memory. * * \author Andrew Rapp */ class XBee { public: XBee(); /** * Reads all available serial bytes until a packet is parsed, an error occurs, or the buffer is empty. * You may call xbee.getResponse().isAvailable() after calling this method to determine if * a packet is ready, or xbee.getResponse().isError() to determine if * a error occurred. *

* This method should always return quickly since it does not wait for serial data to arrive. * You will want to use this method if you are doing other timely stuff in your loop, where * a delay would cause problems. * NOTE: calling this method resets the current response, so make sure you first consume the * current response */ void readPacket(); /** * Waits a maximum of timeout milliseconds for a response packet before timing out; returns true if packet is read. * Returns false if timeout or error occurs. */ bool readPacket(int timeout); /** * Reads until a packet is received or an error occurs. * Caution: use this carefully since if you don't get a response, your Arduino code will hang on this * call forever!! often it's better to use a timeout: readPacket(int) */ void readPacketUntilAvailable(); /** * Starts the serial connection at the supplied baud rate */ void begin(long baud); void getResponse(XBeeResponse &response); /** * Returns a reference to the current response * Note: once readPacket is called again this response will be overwritten! */ XBeeResponse& getResponse(); /** * Sends a XBeeRequest (TX packet) out the serial port */ void send(XBeeRequest &request); //uint8_t sendAndWaitForResponse(XBeeRequest &request, int timeout); /** * Returns a sequential frame id between 1 and 255 */ uint8_t getNextFrameId(); /** * Specify the serial port. Only relevant for Arduinos that support multiple serial ports (e.g. Mega) */ void setSerial(HardwareSerial &serial); //! Timing variables for performance profilling, C. Pham /*! */ long startSend; long stopSend; long startSendRadio; long stopSendRadio; long startWriteLoop; long stopWriteLoop; long startParseMessage; long stopParseMessage; long startTxStatusResponse; long stopTxStatusResponse; long startFetchedTime; long stopFetchedTime; private: bool available(); uint8_t read(); void flush(); void write(uint8_t val); void sendByte(uint8_t b, bool escape); void resetResponse(); XBeeResponse _response; bool _escape; // current packet position for response. just a state variable for packet parsing and has no relevance for the response otherwise uint8_t _pos; // last byte read uint8_t b; uint8_t _checksumTotal; uint8_t _nextFrameId; // buffer for incoming RX packets. holds only the api specific frame data, starting after the api id byte and prior to checksum uint8_t _responseFrameData[MAX_FRAME_DATA_SIZE]; HardwareSerial* _serial; }; /** * All TX packets that support payloads extend this class */ class PayloadRequest : public XBeeRequest { public: PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint8_t payloadLength); /** * Returns the payload of the packet, if not null */ uint8_t* getPayload(); /** * Sets the payload array */ void setPayload(uint8_t* payloadPtr); /** * Returns the length of the payload array, as specified by the user. */ uint8_t getPayloadLength(); /** * Sets the length of the payload to include in the request. For example if the payload array * is 50 bytes and you only want the first 10 to be included in the packet, set the length to 10. * Length must be <= to the array length. */ void setPayloadLength(uint8_t payloadLength); private: uint8_t* _payloadPtr; uint8_t _payloadLength; }; #ifdef SERIES_1 /** * Represents a Series 1 TX packet that corresponds to Api Id: TX_16_REQUEST *

* Be careful not to send a data array larger than the max packet size of your radio. * This class does not perform any validation of packet size and there will be no indication * if the packet is too large, other than you will not get a TX Status response. * The datasheet says 100 bytes is the maximum, although that could change in future firmware. */ class Tx16Request : public PayloadRequest { public: Tx16Request(uint16_t addr16, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); /** * Creates a Unicast Tx16Request with the ACK option and DEFAULT_FRAME_ID */ Tx16Request(uint16_t addr16, uint8_t *payload, uint8_t payloadLength); /** * Creates a default instance of this class. At a minimum you must specify * a payload, payload length and a destination address before sending this request. */ Tx16Request(); uint16_t getAddress16(); void setAddress16(uint16_t addr16); uint8_t getOption(); void setOption(uint8_t option); uint8_t getFrameData(uint8_t pos); uint8_t getFrameDataLength(); protected: private: uint16_t _addr16; uint8_t _option; }; /** * Represents a Series 1 TX packet that corresponds to Api Id: TX_64_REQUEST * * Be careful not to send a data array larger than the max packet size of your radio. * This class does not perform any validation of packet size and there will be no indication * if the packet is too large, other than you will not get a TX Status response. * The datasheet says 100 bytes is the maximum, although that could change in future firmware. */ class Tx64Request : public PayloadRequest { public: Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); /** * Creates a unicast Tx64Request with the ACK option and DEFAULT_FRAME_ID */ Tx64Request(XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength); /** * Creates a default instance of this class. At a minimum you must specify * a payload, payload length and a destination address before sending this request. */ Tx64Request(); XBeeAddress64& getAddress64(); void setAddress64(XBeeAddress64& addr64); // TODO move option to superclass uint8_t getOption(); void setOption(uint8_t option); uint8_t getFrameData(uint8_t pos); uint8_t getFrameDataLength(); private: XBeeAddress64 _addr64; uint8_t _option; }; #endif #ifdef SERIES_2 /** * Represents a Series 2 TX packet that corresponds to Api Id: ZB_TX_REQUEST * * Be careful not to send a data array larger than the max packet size of your radio. * This class does not perform any validation of packet size and there will be no indication * if the packet is too large, other than you will not get a TX Status response. * The datasheet says 72 bytes is the maximum for ZNet firmware and ZB Pro firmware provides * the ATNP command to get the max supported payload size. This command is useful since the * maximum payload size varies according to certain settings, such as encryption. * ZB Pro firmware provides a PAYLOAD_TOO_LARGE that is returned if payload size * exceeds the maximum. */ class ZBTxRequest : public PayloadRequest { public: /** * Creates a unicast ZBTxRequest with the ACK option and DEFAULT_FRAME_ID */ ZBTxRequest(XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength); ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); /** * Creates a default instance of this class. At a minimum you must specify * a payload, payload length and a destination address before sending this request. */ ZBTxRequest(); XBeeAddress64& getAddress64(); uint16_t getAddress16(); uint8_t getBroadcastRadius(); uint8_t getOption(); void setAddress64(XBeeAddress64& addr64); void setAddress16(uint16_t addr16); void setBroadcastRadius(uint8_t broadcastRadius); void setOption(uint8_t option); protected: // declare virtual functions uint8_t getFrameData(uint8_t pos); uint8_t getFrameDataLength(); private: XBeeAddress64 _addr64; uint16_t _addr16; uint8_t _broadcastRadius; uint8_t _option; }; #endif #ifdef SERIES_DIGIMESH /** * Represents a Series 2 TX packet that corresponds to Api Id: ZB_TX_REQUEST * * Be careful not to send a data array larger than the max packet size of your radio. * This class does not perform any validation of packet size and there will be no indication * if the packet is too large, other than you will not get a TX Status response. * The datasheet says 72 bytes is the maximum for ZNet firmware and ZB Pro firmware provides * the ATNP command to get the max supported payload size. This command is useful since the * maximum payload size varies according to certain settings, such as encryption. * ZB Pro firmware provides a PAYLOAD_TOO_LARGE that is returned if payload size * exceeds the maximum. */ class DMTxRequest : public PayloadRequest { public: /** * Creates a unicast DMTxRequest with the ACK option and DEFAULT_FRAME_ID */ DMTxRequest(XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength); DMTxRequest(XBeeAddress64 &addr64, uint8_t broadcastRadius, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); /** * Creates a default instance of this class. At a minimum you must specify * a payload, payload length and a destination address before sending this request. */ DMTxRequest(); XBeeAddress64& getAddress64(); uint8_t getBroadcastRadius(); uint8_t getOption(); void setAddress64(XBeeAddress64& addr64); void setBroadcastRadius(uint8_t broadcastRadius); void setOption(uint8_t option); protected: // declare virtual functions uint8_t getFrameData(uint8_t pos); uint8_t getFrameDataLength(); private: XBeeAddress64 _addr64; uint8_t _broadcastRadius; uint8_t _option; }; #endif /** * Represents an AT Command TX packet * The command is used to configure the serially connected XBee radio */ class AtCommandRequest : public XBeeRequest { public: AtCommandRequest(); AtCommandRequest(uint8_t *command); AtCommandRequest(uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength); uint8_t getFrameData(uint8_t pos); uint8_t getFrameDataLength(); uint8_t* getCommand(); void setCommand(uint8_t* command); uint8_t* getCommandValue(); void setCommandValue(uint8_t* command); uint8_t getCommandValueLength(); void setCommandValueLength(uint8_t length); /** * Clears the optional commandValue and commandValueLength so that a query may be sent */ void clearCommandValue(); //void reset(); private: uint8_t *_command; uint8_t *_commandValue; uint8_t _commandValueLength; }; /** * Represents an Remote AT Command TX packet * The command is used to configure a remote XBee radio */ class RemoteAtCommandRequest : public AtCommandRequest { public: RemoteAtCommandRequest(); /** * Creates a RemoteAtCommandRequest with 16-bit address to set a command. * 64-bit address defaults to broadcast and applyChanges is true. */ RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength); /** * Creates a RemoteAtCommandRequest with 16-bit address to query a command. * 64-bit address defaults to broadcast and applyChanges is true. */ RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command); /** * Creates a RemoteAtCommandRequest with 64-bit address to set a command. * 16-bit address defaults to broadcast and applyChanges is true. */ RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength); /** * Creates a RemoteAtCommandRequest with 16-bit address to query a command. * 16-bit address defaults to broadcast and applyChanges is true. */ RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command); uint16_t getRemoteAddress16(); void setRemoteAddress16(uint16_t remoteAddress16); XBeeAddress64& getRemoteAddress64(); void setRemoteAddress64(XBeeAddress64 &remoteAddress64); bool getApplyChanges(); void setApplyChanges(bool applyChanges); uint8_t getFrameData(uint8_t pos); uint8_t getFrameDataLength(); static XBeeAddress64 broadcastAddress64; // static uint16_t broadcast16Address; private: XBeeAddress64 _remoteAddress64; uint16_t _remoteAddress16; bool _applyChanges; }; #endif //XBee_h