XBee Library in API mode. Based on xbee-arduino.
Dependents: XBee_API_Demo FinalProject FootModule HandController ... more
XBee.h@0:350d308e7b77, 2017-04-23 (annotated)
- Committer:
- lucasec
- Date:
- Sun Apr 23 19:58:12 2017 +0000
- Revision:
- 0:350d308e7b77
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lucasec | 0:350d308e7b77 | 1 | /** |
lucasec | 0:350d308e7b77 | 2 | * Copyright (c) 2009 Andrew Rapp. All rights reserved. |
lucasec | 0:350d308e7b77 | 3 | * |
lucasec | 0:350d308e7b77 | 4 | * This file is part of XBee-Arduino. |
lucasec | 0:350d308e7b77 | 5 | * |
lucasec | 0:350d308e7b77 | 6 | * XBee-Arduino is free software: you can redistribute it and/or modify |
lucasec | 0:350d308e7b77 | 7 | * it under the terms of the GNU General Public License as published by |
lucasec | 0:350d308e7b77 | 8 | * the Free Software Foundation, either version 3 of the License, or |
lucasec | 0:350d308e7b77 | 9 | * (at your option) any later version. |
lucasec | 0:350d308e7b77 | 10 | * |
lucasec | 0:350d308e7b77 | 11 | * XBee-Arduino is distributed in the hope that it will be useful, |
lucasec | 0:350d308e7b77 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
lucasec | 0:350d308e7b77 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
lucasec | 0:350d308e7b77 | 14 | * GNU General Public License for more details. |
lucasec | 0:350d308e7b77 | 15 | * |
lucasec | 0:350d308e7b77 | 16 | * You should have received a copy of the GNU General Public License |
lucasec | 0:350d308e7b77 | 17 | * along with XBee-Arduino. If not, see <http://www.gnu.org/licenses/>. |
lucasec | 0:350d308e7b77 | 18 | */ |
lucasec | 0:350d308e7b77 | 19 | |
lucasec | 0:350d308e7b77 | 20 | #ifndef XBee_h |
lucasec | 0:350d308e7b77 | 21 | #define XBee_h |
lucasec | 0:350d308e7b77 | 22 | |
lucasec | 0:350d308e7b77 | 23 | #include "mbed.h" |
lucasec | 0:350d308e7b77 | 24 | #include <inttypes.h> |
lucasec | 0:350d308e7b77 | 25 | |
lucasec | 0:350d308e7b77 | 26 | #define SERIES_1 |
lucasec | 0:350d308e7b77 | 27 | #define SERIES_2 |
lucasec | 0:350d308e7b77 | 28 | |
lucasec | 0:350d308e7b77 | 29 | // set to ATAP value of XBee. AP=2 is recommended |
lucasec | 0:350d308e7b77 | 30 | #define ATAP 2 |
lucasec | 0:350d308e7b77 | 31 | |
lucasec | 0:350d308e7b77 | 32 | #define START_BYTE 0x7e |
lucasec | 0:350d308e7b77 | 33 | #define ESCAPE 0x7d |
lucasec | 0:350d308e7b77 | 34 | #define XON 0x11 |
lucasec | 0:350d308e7b77 | 35 | #define XOFF 0x13 |
lucasec | 0:350d308e7b77 | 36 | |
lucasec | 0:350d308e7b77 | 37 | // This value determines the size of the byte array for receiving RX packets |
lucasec | 0:350d308e7b77 | 38 | // Most users won't be dealing with packets this large so you can adjust this |
lucasec | 0:350d308e7b77 | 39 | // value to reduce memory consumption. But, remember that |
lucasec | 0:350d308e7b77 | 40 | // if a RX packet exceeds this size, it cannot be parsed! |
lucasec | 0:350d308e7b77 | 41 | |
lucasec | 0:350d308e7b77 | 42 | // 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 |
lucasec | 0:350d308e7b77 | 43 | #define MAX_FRAME_DATA_SIZE 110 |
lucasec | 0:350d308e7b77 | 44 | |
lucasec | 0:350d308e7b77 | 45 | #define BROADCAST_ADDRESS 0xffff |
lucasec | 0:350d308e7b77 | 46 | #define ZB_BROADCAST_ADDRESS 0xfffe |
lucasec | 0:350d308e7b77 | 47 | |
lucasec | 0:350d308e7b77 | 48 | // 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) |
lucasec | 0:350d308e7b77 | 49 | #define ZB_TX_API_LENGTH 12 |
lucasec | 0:350d308e7b77 | 50 | #define ZB_EXPLICIT_TX_API_LENGTH 18 |
lucasec | 0:350d308e7b77 | 51 | #define TX_16_API_LENGTH 3 |
lucasec | 0:350d308e7b77 | 52 | #define TX_64_API_LENGTH 9 |
lucasec | 0:350d308e7b77 | 53 | #define AT_COMMAND_API_LENGTH 2 |
lucasec | 0:350d308e7b77 | 54 | #define REMOTE_AT_COMMAND_API_LENGTH 13 |
lucasec | 0:350d308e7b77 | 55 | // start/length(2)/api/frameid/checksum bytes |
lucasec | 0:350d308e7b77 | 56 | #define PACKET_OVERHEAD_LENGTH 6 |
lucasec | 0:350d308e7b77 | 57 | // api is always the third byte in packet |
lucasec | 0:350d308e7b77 | 58 | #define API_ID_INDEX 3 |
lucasec | 0:350d308e7b77 | 59 | |
lucasec | 0:350d308e7b77 | 60 | // frame position of rssi byte |
lucasec | 0:350d308e7b77 | 61 | #define RX_16_RSSI_OFFSET 2 |
lucasec | 0:350d308e7b77 | 62 | #define RX_64_RSSI_OFFSET 8 |
lucasec | 0:350d308e7b77 | 63 | |
lucasec | 0:350d308e7b77 | 64 | #define DEFAULT_FRAME_ID 1 |
lucasec | 0:350d308e7b77 | 65 | #define NO_RESPONSE_FRAME_ID 0 |
lucasec | 0:350d308e7b77 | 66 | |
lucasec | 0:350d308e7b77 | 67 | // These are the parameters used by the XBee ZB modules when you do a |
lucasec | 0:350d308e7b77 | 68 | // regular "ZB TX request". |
lucasec | 0:350d308e7b77 | 69 | #define DEFAULT_ENDPOINT 232 |
lucasec | 0:350d308e7b77 | 70 | #define DEFAULT_CLUSTER_ID 0x0011 |
lucasec | 0:350d308e7b77 | 71 | #define DEFAULT_PROFILE_ID 0xc105 |
lucasec | 0:350d308e7b77 | 72 | |
lucasec | 0:350d308e7b77 | 73 | // TODO put in tx16 class |
lucasec | 0:350d308e7b77 | 74 | #define ACK_OPTION 0 |
lucasec | 0:350d308e7b77 | 75 | #define DISABLE_ACK_OPTION 1 |
lucasec | 0:350d308e7b77 | 76 | #define BROADCAST_OPTION 4 |
lucasec | 0:350d308e7b77 | 77 | |
lucasec | 0:350d308e7b77 | 78 | // RX options |
lucasec | 0:350d308e7b77 | 79 | #define ZB_PACKET_ACKNOWLEDGED 0x01 |
lucasec | 0:350d308e7b77 | 80 | #define ZB_BROADCAST_PACKET 0x02 |
lucasec | 0:350d308e7b77 | 81 | |
lucasec | 0:350d308e7b77 | 82 | // not everything is implemented! |
lucasec | 0:350d308e7b77 | 83 | /** |
lucasec | 0:350d308e7b77 | 84 | * Api Id constants |
lucasec | 0:350d308e7b77 | 85 | */ |
lucasec | 0:350d308e7b77 | 86 | #define TX_64_REQUEST 0x0 |
lucasec | 0:350d308e7b77 | 87 | #define TX_16_REQUEST 0x1 |
lucasec | 0:350d308e7b77 | 88 | #define AT_COMMAND_REQUEST 0x08 |
lucasec | 0:350d308e7b77 | 89 | #define AT_COMMAND_QUEUE_REQUEST 0x09 |
lucasec | 0:350d308e7b77 | 90 | #define REMOTE_AT_REQUEST 0x17 |
lucasec | 0:350d308e7b77 | 91 | #define ZB_TX_REQUEST 0x10 |
lucasec | 0:350d308e7b77 | 92 | #define ZB_EXPLICIT_TX_REQUEST 0x11 |
lucasec | 0:350d308e7b77 | 93 | #define RX_64_RESPONSE 0x80 |
lucasec | 0:350d308e7b77 | 94 | #define RX_16_RESPONSE 0x81 |
lucasec | 0:350d308e7b77 | 95 | #define RX_64_IO_RESPONSE 0x82 |
lucasec | 0:350d308e7b77 | 96 | #define RX_16_IO_RESPONSE 0x83 |
lucasec | 0:350d308e7b77 | 97 | #define AT_RESPONSE 0x88 |
lucasec | 0:350d308e7b77 | 98 | #define TX_STATUS_RESPONSE 0x89 |
lucasec | 0:350d308e7b77 | 99 | #define MODEM_STATUS_RESPONSE 0x8a |
lucasec | 0:350d308e7b77 | 100 | #define ZB_RX_RESPONSE 0x90 |
lucasec | 0:350d308e7b77 | 101 | #define ZB_EXPLICIT_RX_RESPONSE 0x91 |
lucasec | 0:350d308e7b77 | 102 | #define ZB_TX_STATUS_RESPONSE 0x8b |
lucasec | 0:350d308e7b77 | 103 | #define ZB_IO_SAMPLE_RESPONSE 0x92 |
lucasec | 0:350d308e7b77 | 104 | #define ZB_IO_NODE_IDENTIFIER_RESPONSE 0x95 |
lucasec | 0:350d308e7b77 | 105 | #define AT_COMMAND_RESPONSE 0x88 |
lucasec | 0:350d308e7b77 | 106 | #define REMOTE_AT_COMMAND_RESPONSE 0x97 |
lucasec | 0:350d308e7b77 | 107 | |
lucasec | 0:350d308e7b77 | 108 | |
lucasec | 0:350d308e7b77 | 109 | /** |
lucasec | 0:350d308e7b77 | 110 | * TX STATUS constants |
lucasec | 0:350d308e7b77 | 111 | */ |
lucasec | 0:350d308e7b77 | 112 | #define SUCCESS 0x0 |
lucasec | 0:350d308e7b77 | 113 | #define CCA_FAILURE 0x2 |
lucasec | 0:350d308e7b77 | 114 | #define INVALID_DESTINATION_ENDPOINT_SUCCESS 0x15 |
lucasec | 0:350d308e7b77 | 115 | #define NETWORK_ACK_FAILURE 0x21 |
lucasec | 0:350d308e7b77 | 116 | #define NOT_JOINED_TO_NETWORK 0x22 |
lucasec | 0:350d308e7b77 | 117 | #define SELF_ADDRESSED 0x23 |
lucasec | 0:350d308e7b77 | 118 | #define ADDRESS_NOT_FOUND 0x24 |
lucasec | 0:350d308e7b77 | 119 | #define ROUTE_NOT_FOUND 0x25 |
lucasec | 0:350d308e7b77 | 120 | #define PAYLOAD_TOO_LARGE 0x74 |
lucasec | 0:350d308e7b77 | 121 | // Returned by XBeeWithCallbacks::waitForStatus on timeout |
lucasec | 0:350d308e7b77 | 122 | #define XBEE_WAIT_TIMEOUT 0xff |
lucasec | 0:350d308e7b77 | 123 | |
lucasec | 0:350d308e7b77 | 124 | // modem status |
lucasec | 0:350d308e7b77 | 125 | #define HARDWARE_RESET 0 |
lucasec | 0:350d308e7b77 | 126 | #define WATCHDOG_TIMER_RESET 1 |
lucasec | 0:350d308e7b77 | 127 | #define ASSOCIATED 2 |
lucasec | 0:350d308e7b77 | 128 | #define DISASSOCIATED 3 |
lucasec | 0:350d308e7b77 | 129 | #define SYNCHRONIZATION_LOST 4 |
lucasec | 0:350d308e7b77 | 130 | #define COORDINATOR_REALIGNMENT 5 |
lucasec | 0:350d308e7b77 | 131 | #define COORDINATOR_STARTED 6 |
lucasec | 0:350d308e7b77 | 132 | |
lucasec | 0:350d308e7b77 | 133 | #define ZB_BROADCAST_RADIUS_MAX_HOPS 0 |
lucasec | 0:350d308e7b77 | 134 | |
lucasec | 0:350d308e7b77 | 135 | #define ZB_TX_UNICAST 0 |
lucasec | 0:350d308e7b77 | 136 | #define ZB_TX_BROADCAST 8 |
lucasec | 0:350d308e7b77 | 137 | |
lucasec | 0:350d308e7b77 | 138 | #define AT_OK 0 |
lucasec | 0:350d308e7b77 | 139 | #define AT_ERROR 1 |
lucasec | 0:350d308e7b77 | 140 | #define AT_INVALID_COMMAND 2 |
lucasec | 0:350d308e7b77 | 141 | #define AT_INVALID_PARAMETER 3 |
lucasec | 0:350d308e7b77 | 142 | #define AT_NO_RESPONSE 4 |
lucasec | 0:350d308e7b77 | 143 | |
lucasec | 0:350d308e7b77 | 144 | #define NO_ERROR 0 |
lucasec | 0:350d308e7b77 | 145 | #define CHECKSUM_FAILURE 1 |
lucasec | 0:350d308e7b77 | 146 | #define PACKET_EXCEEDS_BYTE_ARRAY_LENGTH 2 |
lucasec | 0:350d308e7b77 | 147 | #define UNEXPECTED_START_BYTE 3 |
lucasec | 0:350d308e7b77 | 148 | |
lucasec | 0:350d308e7b77 | 149 | /** |
lucasec | 0:350d308e7b77 | 150 | * C++11 introduced the constexpr as a hint to the compiler that things |
lucasec | 0:350d308e7b77 | 151 | * can be evaluated at compiletime. This can help to remove |
lucasec | 0:350d308e7b77 | 152 | * startup code for global objects, or otherwise help the compiler to |
lucasec | 0:350d308e7b77 | 153 | * optimize. Since the keyword is introduced in C++11, but supporting |
lucasec | 0:350d308e7b77 | 154 | * older compilers is a matter of removing the keyword, we use a macro |
lucasec | 0:350d308e7b77 | 155 | * for this. |
lucasec | 0:350d308e7b77 | 156 | */ |
lucasec | 0:350d308e7b77 | 157 | #if __cplusplus >= 201103L |
lucasec | 0:350d308e7b77 | 158 | #define CONSTEXPR constexpr |
lucasec | 0:350d308e7b77 | 159 | #else |
lucasec | 0:350d308e7b77 | 160 | #define CONSTEXPR |
lucasec | 0:350d308e7b77 | 161 | #endif |
lucasec | 0:350d308e7b77 | 162 | |
lucasec | 0:350d308e7b77 | 163 | /** |
lucasec | 0:350d308e7b77 | 164 | * The super class of all XBee responses (RX packets) |
lucasec | 0:350d308e7b77 | 165 | * Users should never attempt to create an instance of this class; instead |
lucasec | 0:350d308e7b77 | 166 | * create an instance of a subclass |
lucasec | 0:350d308e7b77 | 167 | * It is recommend to reuse subclasses to conserve memory |
lucasec | 0:350d308e7b77 | 168 | */ |
lucasec | 0:350d308e7b77 | 169 | class XBeeResponse { |
lucasec | 0:350d308e7b77 | 170 | public: |
lucasec | 0:350d308e7b77 | 171 | //static const int MODEM_STATUS = 0x8a; |
lucasec | 0:350d308e7b77 | 172 | /** |
lucasec | 0:350d308e7b77 | 173 | * Default constructor |
lucasec | 0:350d308e7b77 | 174 | */ |
lucasec | 0:350d308e7b77 | 175 | XBeeResponse(); |
lucasec | 0:350d308e7b77 | 176 | /** |
lucasec | 0:350d308e7b77 | 177 | * Returns Api Id of the response |
lucasec | 0:350d308e7b77 | 178 | */ |
lucasec | 0:350d308e7b77 | 179 | uint8_t getApiId(); |
lucasec | 0:350d308e7b77 | 180 | void setApiId(uint8_t apiId); |
lucasec | 0:350d308e7b77 | 181 | /** |
lucasec | 0:350d308e7b77 | 182 | * Returns the MSB length of the packet |
lucasec | 0:350d308e7b77 | 183 | */ |
lucasec | 0:350d308e7b77 | 184 | uint8_t getMsbLength(); |
lucasec | 0:350d308e7b77 | 185 | void setMsbLength(uint8_t msbLength); |
lucasec | 0:350d308e7b77 | 186 | /** |
lucasec | 0:350d308e7b77 | 187 | * Returns the LSB length of the packet |
lucasec | 0:350d308e7b77 | 188 | */ |
lucasec | 0:350d308e7b77 | 189 | uint8_t getLsbLength(); |
lucasec | 0:350d308e7b77 | 190 | void setLsbLength(uint8_t lsbLength); |
lucasec | 0:350d308e7b77 | 191 | /** |
lucasec | 0:350d308e7b77 | 192 | * Returns the packet checksum |
lucasec | 0:350d308e7b77 | 193 | */ |
lucasec | 0:350d308e7b77 | 194 | uint8_t getChecksum(); |
lucasec | 0:350d308e7b77 | 195 | void setChecksum(uint8_t checksum); |
lucasec | 0:350d308e7b77 | 196 | /** |
lucasec | 0:350d308e7b77 | 197 | * Returns the length of the frame data: all bytes after the api id, and prior to the checksum |
lucasec | 0:350d308e7b77 | 198 | * Note up to release 0.1.2, this was incorrectly including the checksum in the length. |
lucasec | 0:350d308e7b77 | 199 | */ |
lucasec | 0:350d308e7b77 | 200 | uint8_t getFrameDataLength(); |
lucasec | 0:350d308e7b77 | 201 | void setFrameData(uint8_t* frameDataPtr); |
lucasec | 0:350d308e7b77 | 202 | /** |
lucasec | 0:350d308e7b77 | 203 | * Returns the buffer that contains the response. |
lucasec | 0:350d308e7b77 | 204 | * Starts with byte that follows API ID and includes all bytes prior to the checksum |
lucasec | 0:350d308e7b77 | 205 | * Length is specified by getFrameDataLength() |
lucasec | 0:350d308e7b77 | 206 | * Note: Unlike Digi's definition of the frame data, this does not start with the API ID.. |
lucasec | 0:350d308e7b77 | 207 | * The reason for this is all responses include an API ID, whereas my frame data |
lucasec | 0:350d308e7b77 | 208 | * includes only the API specific data. |
lucasec | 0:350d308e7b77 | 209 | */ |
lucasec | 0:350d308e7b77 | 210 | uint8_t* getFrameData(); |
lucasec | 0:350d308e7b77 | 211 | |
lucasec | 0:350d308e7b77 | 212 | void setFrameLength(uint8_t frameLength); |
lucasec | 0:350d308e7b77 | 213 | // to support future 65535 byte packets I guess |
lucasec | 0:350d308e7b77 | 214 | /** |
lucasec | 0:350d308e7b77 | 215 | * Returns the length of the packet |
lucasec | 0:350d308e7b77 | 216 | */ |
lucasec | 0:350d308e7b77 | 217 | uint16_t getPacketLength(); |
lucasec | 0:350d308e7b77 | 218 | /** |
lucasec | 0:350d308e7b77 | 219 | * Resets the response to default values |
lucasec | 0:350d308e7b77 | 220 | */ |
lucasec | 0:350d308e7b77 | 221 | void reset(); |
lucasec | 0:350d308e7b77 | 222 | /** |
lucasec | 0:350d308e7b77 | 223 | * Initializes the response |
lucasec | 0:350d308e7b77 | 224 | */ |
lucasec | 0:350d308e7b77 | 225 | void init(); |
lucasec | 0:350d308e7b77 | 226 | #ifdef SERIES_2 |
lucasec | 0:350d308e7b77 | 227 | /** |
lucasec | 0:350d308e7b77 | 228 | * Call with instance of ZBTxStatusResponse class only if getApiId() == ZB_TX_STATUS_RESPONSE |
lucasec | 0:350d308e7b77 | 229 | * to populate response |
lucasec | 0:350d308e7b77 | 230 | */ |
lucasec | 0:350d308e7b77 | 231 | void getZBTxStatusResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 232 | /** |
lucasec | 0:350d308e7b77 | 233 | * Call with instance of ZBRxResponse class only if getApiId() == ZB_RX_RESPONSE |
lucasec | 0:350d308e7b77 | 234 | * to populate response |
lucasec | 0:350d308e7b77 | 235 | */ |
lucasec | 0:350d308e7b77 | 236 | void getZBRxResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 237 | /** |
lucasec | 0:350d308e7b77 | 238 | * Call with instance of ZBExplicitRxResponse class only if getApiId() == ZB_EXPLICIT_RX_RESPONSE |
lucasec | 0:350d308e7b77 | 239 | * to populate response |
lucasec | 0:350d308e7b77 | 240 | */ |
lucasec | 0:350d308e7b77 | 241 | void getZBExplicitRxResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 242 | /** |
lucasec | 0:350d308e7b77 | 243 | * Call with instance of ZBRxIoSampleResponse class only if getApiId() == ZB_IO_SAMPLE_RESPONSE |
lucasec | 0:350d308e7b77 | 244 | * to populate response |
lucasec | 0:350d308e7b77 | 245 | */ |
lucasec | 0:350d308e7b77 | 246 | void getZBRxIoSampleResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 247 | #endif |
lucasec | 0:350d308e7b77 | 248 | #ifdef SERIES_1 |
lucasec | 0:350d308e7b77 | 249 | /** |
lucasec | 0:350d308e7b77 | 250 | * Call with instance of TxStatusResponse only if getApiId() == TX_STATUS_RESPONSE |
lucasec | 0:350d308e7b77 | 251 | */ |
lucasec | 0:350d308e7b77 | 252 | void getTxStatusResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 253 | /** |
lucasec | 0:350d308e7b77 | 254 | * Call with instance of Rx16Response only if getApiId() == RX_16_RESPONSE |
lucasec | 0:350d308e7b77 | 255 | */ |
lucasec | 0:350d308e7b77 | 256 | void getRx16Response(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 257 | /** |
lucasec | 0:350d308e7b77 | 258 | * Call with instance of Rx64Response only if getApiId() == RX_64_RESPONSE |
lucasec | 0:350d308e7b77 | 259 | */ |
lucasec | 0:350d308e7b77 | 260 | void getRx64Response(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 261 | /** |
lucasec | 0:350d308e7b77 | 262 | * Call with instance of Rx16IoSampleResponse only if getApiId() == RX_16_IO_RESPONSE |
lucasec | 0:350d308e7b77 | 263 | */ |
lucasec | 0:350d308e7b77 | 264 | void getRx16IoSampleResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 265 | /** |
lucasec | 0:350d308e7b77 | 266 | * Call with instance of Rx64IoSampleResponse only if getApiId() == RX_64_IO_RESPONSE |
lucasec | 0:350d308e7b77 | 267 | */ |
lucasec | 0:350d308e7b77 | 268 | void getRx64IoSampleResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 269 | #endif |
lucasec | 0:350d308e7b77 | 270 | /** |
lucasec | 0:350d308e7b77 | 271 | * Call with instance of AtCommandResponse only if getApiId() == AT_COMMAND_RESPONSE |
lucasec | 0:350d308e7b77 | 272 | */ |
lucasec | 0:350d308e7b77 | 273 | void getAtCommandResponse(XBeeResponse &responses); |
lucasec | 0:350d308e7b77 | 274 | /** |
lucasec | 0:350d308e7b77 | 275 | * Call with instance of RemoteAtCommandResponse only if getApiId() == REMOTE_AT_COMMAND_RESPONSE |
lucasec | 0:350d308e7b77 | 276 | */ |
lucasec | 0:350d308e7b77 | 277 | void getRemoteAtCommandResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 278 | /** |
lucasec | 0:350d308e7b77 | 279 | * Call with instance of ModemStatusResponse only if getApiId() == MODEM_STATUS_RESPONSE |
lucasec | 0:350d308e7b77 | 280 | */ |
lucasec | 0:350d308e7b77 | 281 | void getModemStatusResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 282 | /** |
lucasec | 0:350d308e7b77 | 283 | * Returns true if the response has been successfully parsed and is complete and ready for use |
lucasec | 0:350d308e7b77 | 284 | */ |
lucasec | 0:350d308e7b77 | 285 | bool isAvailable(); |
lucasec | 0:350d308e7b77 | 286 | void setAvailable(bool complete); |
lucasec | 0:350d308e7b77 | 287 | /** |
lucasec | 0:350d308e7b77 | 288 | * Returns true if the response contains errors |
lucasec | 0:350d308e7b77 | 289 | */ |
lucasec | 0:350d308e7b77 | 290 | bool isError(); |
lucasec | 0:350d308e7b77 | 291 | /** |
lucasec | 0:350d308e7b77 | 292 | * Returns an error code, or zero, if successful. |
lucasec | 0:350d308e7b77 | 293 | * Error codes include: CHECKSUM_FAILURE, PACKET_EXCEEDS_BYTE_ARRAY_LENGTH, UNEXPECTED_START_BYTE |
lucasec | 0:350d308e7b77 | 294 | */ |
lucasec | 0:350d308e7b77 | 295 | uint8_t getErrorCode(); |
lucasec | 0:350d308e7b77 | 296 | void setErrorCode(uint8_t errorCode); |
lucasec | 0:350d308e7b77 | 297 | protected: |
lucasec | 0:350d308e7b77 | 298 | // pointer to frameData |
lucasec | 0:350d308e7b77 | 299 | uint8_t* _frameDataPtr; |
lucasec | 0:350d308e7b77 | 300 | private: |
lucasec | 0:350d308e7b77 | 301 | void setCommon(XBeeResponse &target); |
lucasec | 0:350d308e7b77 | 302 | uint8_t _apiId; |
lucasec | 0:350d308e7b77 | 303 | uint8_t _msbLength; |
lucasec | 0:350d308e7b77 | 304 | uint8_t _lsbLength; |
lucasec | 0:350d308e7b77 | 305 | uint8_t _checksum; |
lucasec | 0:350d308e7b77 | 306 | uint8_t _frameLength; |
lucasec | 0:350d308e7b77 | 307 | bool _complete; |
lucasec | 0:350d308e7b77 | 308 | uint8_t _errorCode; |
lucasec | 0:350d308e7b77 | 309 | }; |
lucasec | 0:350d308e7b77 | 310 | |
lucasec | 0:350d308e7b77 | 311 | class XBeeAddress { |
lucasec | 0:350d308e7b77 | 312 | public: |
lucasec | 0:350d308e7b77 | 313 | CONSTEXPR XBeeAddress() {}; |
lucasec | 0:350d308e7b77 | 314 | }; |
lucasec | 0:350d308e7b77 | 315 | |
lucasec | 0:350d308e7b77 | 316 | /** |
lucasec | 0:350d308e7b77 | 317 | * Represents a 64-bit XBee Address |
lucasec | 0:350d308e7b77 | 318 | * |
lucasec | 0:350d308e7b77 | 319 | * Note that avr-gcc as of 4.9 doesn't optimize uint64_t very well, so |
lucasec | 0:350d308e7b77 | 320 | * for the smallest and fastest code, use msb and lsb separately. See |
lucasec | 0:350d308e7b77 | 321 | * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66511 |
lucasec | 0:350d308e7b77 | 322 | */ |
lucasec | 0:350d308e7b77 | 323 | class XBeeAddress64 : public XBeeAddress { |
lucasec | 0:350d308e7b77 | 324 | public: |
lucasec | 0:350d308e7b77 | 325 | CONSTEXPR XBeeAddress64(uint64_t addr) : _msb(addr >> 32), _lsb(addr) {} |
lucasec | 0:350d308e7b77 | 326 | CONSTEXPR XBeeAddress64(uint32_t msb, uint32_t lsb) : _msb(msb), _lsb(lsb) {} |
lucasec | 0:350d308e7b77 | 327 | CONSTEXPR XBeeAddress64() : _msb(0), _lsb(0) {} |
lucasec | 0:350d308e7b77 | 328 | uint32_t getMsb() {return _msb;} |
lucasec | 0:350d308e7b77 | 329 | uint32_t getLsb() {return _lsb;} |
lucasec | 0:350d308e7b77 | 330 | uint64_t get() {return (static_cast<uint64_t>(_msb) << 32) | _lsb;} |
lucasec | 0:350d308e7b77 | 331 | operator uint64_t() {return get();} |
lucasec | 0:350d308e7b77 | 332 | void setMsb(uint32_t msb) {_msb = msb;} |
lucasec | 0:350d308e7b77 | 333 | void setLsb(uint32_t lsb) {_lsb = lsb;} |
lucasec | 0:350d308e7b77 | 334 | void set(uint64_t addr) { |
lucasec | 0:350d308e7b77 | 335 | _msb = addr >> 32; |
lucasec | 0:350d308e7b77 | 336 | _lsb = addr; |
lucasec | 0:350d308e7b77 | 337 | } |
lucasec | 0:350d308e7b77 | 338 | private: |
lucasec | 0:350d308e7b77 | 339 | // Once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66511 is |
lucasec | 0:350d308e7b77 | 340 | // fixed, it might make sense to merge these into a uint64_t. |
lucasec | 0:350d308e7b77 | 341 | uint32_t _msb; |
lucasec | 0:350d308e7b77 | 342 | uint32_t _lsb; |
lucasec | 0:350d308e7b77 | 343 | }; |
lucasec | 0:350d308e7b77 | 344 | |
lucasec | 0:350d308e7b77 | 345 | //class XBeeAddress16 : public XBeeAddress { |
lucasec | 0:350d308e7b77 | 346 | //public: |
lucasec | 0:350d308e7b77 | 347 | // XBeeAddress16(uint16_t addr); |
lucasec | 0:350d308e7b77 | 348 | // XBeeAddress16(); |
lucasec | 0:350d308e7b77 | 349 | // uint16_t getAddress(); |
lucasec | 0:350d308e7b77 | 350 | // void setAddress(uint16_t addr); |
lucasec | 0:350d308e7b77 | 351 | //private: |
lucasec | 0:350d308e7b77 | 352 | // uint16_t _addr;q |
lucasec | 0:350d308e7b77 | 353 | //}; |
lucasec | 0:350d308e7b77 | 354 | |
lucasec | 0:350d308e7b77 | 355 | /** |
lucasec | 0:350d308e7b77 | 356 | * This class is extended by all Responses that include a frame id |
lucasec | 0:350d308e7b77 | 357 | */ |
lucasec | 0:350d308e7b77 | 358 | class FrameIdResponse : public XBeeResponse { |
lucasec | 0:350d308e7b77 | 359 | public: |
lucasec | 0:350d308e7b77 | 360 | FrameIdResponse(); |
lucasec | 0:350d308e7b77 | 361 | uint8_t getFrameId(); |
lucasec | 0:350d308e7b77 | 362 | private: |
lucasec | 0:350d308e7b77 | 363 | uint8_t _frameId; |
lucasec | 0:350d308e7b77 | 364 | }; |
lucasec | 0:350d308e7b77 | 365 | |
lucasec | 0:350d308e7b77 | 366 | /** |
lucasec | 0:350d308e7b77 | 367 | * Common functionality for both Series 1 and 2 data RX data packets |
lucasec | 0:350d308e7b77 | 368 | */ |
lucasec | 0:350d308e7b77 | 369 | class RxDataResponse : public XBeeResponse { |
lucasec | 0:350d308e7b77 | 370 | public: |
lucasec | 0:350d308e7b77 | 371 | RxDataResponse(); |
lucasec | 0:350d308e7b77 | 372 | /** |
lucasec | 0:350d308e7b77 | 373 | * Returns the specified index of the payload. The index may be 0 to getDataLength() - 1 |
lucasec | 0:350d308e7b77 | 374 | * This method is deprecated; use uint8_t* getData() |
lucasec | 0:350d308e7b77 | 375 | */ |
lucasec | 0:350d308e7b77 | 376 | uint8_t getData(int index); |
lucasec | 0:350d308e7b77 | 377 | /** |
lucasec | 0:350d308e7b77 | 378 | * Returns the payload array. This may be accessed from index 0 to getDataLength() - 1 |
lucasec | 0:350d308e7b77 | 379 | */ |
lucasec | 0:350d308e7b77 | 380 | uint8_t* getData(); |
lucasec | 0:350d308e7b77 | 381 | /** |
lucasec | 0:350d308e7b77 | 382 | * Returns the length of the payload |
lucasec | 0:350d308e7b77 | 383 | */ |
lucasec | 0:350d308e7b77 | 384 | virtual uint8_t getDataLength() = 0; |
lucasec | 0:350d308e7b77 | 385 | /** |
lucasec | 0:350d308e7b77 | 386 | * Returns the position in the frame data where the data begins |
lucasec | 0:350d308e7b77 | 387 | */ |
lucasec | 0:350d308e7b77 | 388 | virtual uint8_t getDataOffset() = 0; |
lucasec | 0:350d308e7b77 | 389 | }; |
lucasec | 0:350d308e7b77 | 390 | |
lucasec | 0:350d308e7b77 | 391 | // getResponse to return the proper subclass: |
lucasec | 0:350d308e7b77 | 392 | // we maintain a pointer to each type of response, when a response is parsed, it is allocated only if NULL |
lucasec | 0:350d308e7b77 | 393 | // can we allocate an object in a function? |
lucasec | 0:350d308e7b77 | 394 | |
lucasec | 0:350d308e7b77 | 395 | #ifdef SERIES_2 |
lucasec | 0:350d308e7b77 | 396 | /** |
lucasec | 0:350d308e7b77 | 397 | * Represents a Series 2 TX status packet |
lucasec | 0:350d308e7b77 | 398 | */ |
lucasec | 0:350d308e7b77 | 399 | class ZBTxStatusResponse : public FrameIdResponse { |
lucasec | 0:350d308e7b77 | 400 | public: |
lucasec | 0:350d308e7b77 | 401 | ZBTxStatusResponse(); |
lucasec | 0:350d308e7b77 | 402 | uint16_t getRemoteAddress(); |
lucasec | 0:350d308e7b77 | 403 | uint8_t getTxRetryCount(); |
lucasec | 0:350d308e7b77 | 404 | uint8_t getDeliveryStatus(); |
lucasec | 0:350d308e7b77 | 405 | uint8_t getDiscoveryStatus(); |
lucasec | 0:350d308e7b77 | 406 | bool isSuccess(); |
lucasec | 0:350d308e7b77 | 407 | |
lucasec | 0:350d308e7b77 | 408 | static const uint8_t API_ID = ZB_TX_STATUS_RESPONSE; |
lucasec | 0:350d308e7b77 | 409 | }; |
lucasec | 0:350d308e7b77 | 410 | |
lucasec | 0:350d308e7b77 | 411 | /** |
lucasec | 0:350d308e7b77 | 412 | * Represents a Series 2 RX packet |
lucasec | 0:350d308e7b77 | 413 | */ |
lucasec | 0:350d308e7b77 | 414 | class ZBRxResponse : public RxDataResponse { |
lucasec | 0:350d308e7b77 | 415 | public: |
lucasec | 0:350d308e7b77 | 416 | ZBRxResponse(); |
lucasec | 0:350d308e7b77 | 417 | XBeeAddress64& getRemoteAddress64(); |
lucasec | 0:350d308e7b77 | 418 | uint16_t getRemoteAddress16(); |
lucasec | 0:350d308e7b77 | 419 | uint8_t getOption(); |
lucasec | 0:350d308e7b77 | 420 | virtual uint8_t getDataLength(); |
lucasec | 0:350d308e7b77 | 421 | // frame position where data starts |
lucasec | 0:350d308e7b77 | 422 | virtual uint8_t getDataOffset(); |
lucasec | 0:350d308e7b77 | 423 | |
lucasec | 0:350d308e7b77 | 424 | static const uint8_t API_ID = ZB_RX_RESPONSE; |
lucasec | 0:350d308e7b77 | 425 | private: |
lucasec | 0:350d308e7b77 | 426 | XBeeAddress64 _remoteAddress64; |
lucasec | 0:350d308e7b77 | 427 | }; |
lucasec | 0:350d308e7b77 | 428 | |
lucasec | 0:350d308e7b77 | 429 | /** |
lucasec | 0:350d308e7b77 | 430 | * Represents a Series 2 Explicit RX packet |
lucasec | 0:350d308e7b77 | 431 | * |
lucasec | 0:350d308e7b77 | 432 | * Note: The receive these responses, set AO=1. With the default AO=0, |
lucasec | 0:350d308e7b77 | 433 | * you will receive ZBRxResponses, not knowing exact details. |
lucasec | 0:350d308e7b77 | 434 | */ |
lucasec | 0:350d308e7b77 | 435 | class ZBExplicitRxResponse : public ZBRxResponse { |
lucasec | 0:350d308e7b77 | 436 | public: |
lucasec | 0:350d308e7b77 | 437 | ZBExplicitRxResponse(); |
lucasec | 0:350d308e7b77 | 438 | uint8_t getSrcEndpoint(); |
lucasec | 0:350d308e7b77 | 439 | uint8_t getDstEndpoint(); |
lucasec | 0:350d308e7b77 | 440 | uint16_t getClusterId(); |
lucasec | 0:350d308e7b77 | 441 | uint16_t getProfileId(); |
lucasec | 0:350d308e7b77 | 442 | uint8_t getOption(); |
lucasec | 0:350d308e7b77 | 443 | virtual uint8_t getDataLength(); |
lucasec | 0:350d308e7b77 | 444 | // frame position where data starts |
lucasec | 0:350d308e7b77 | 445 | virtual uint8_t getDataOffset(); |
lucasec | 0:350d308e7b77 | 446 | |
lucasec | 0:350d308e7b77 | 447 | static const uint8_t API_ID = ZB_EXPLICIT_RX_RESPONSE; |
lucasec | 0:350d308e7b77 | 448 | }; |
lucasec | 0:350d308e7b77 | 449 | |
lucasec | 0:350d308e7b77 | 450 | /** |
lucasec | 0:350d308e7b77 | 451 | * Represents a Series 2 RX I/O Sample packet |
lucasec | 0:350d308e7b77 | 452 | */ |
lucasec | 0:350d308e7b77 | 453 | class ZBRxIoSampleResponse : public ZBRxResponse { |
lucasec | 0:350d308e7b77 | 454 | public: |
lucasec | 0:350d308e7b77 | 455 | ZBRxIoSampleResponse(); |
lucasec | 0:350d308e7b77 | 456 | bool containsAnalog(); |
lucasec | 0:350d308e7b77 | 457 | bool containsDigital(); |
lucasec | 0:350d308e7b77 | 458 | /** |
lucasec | 0:350d308e7b77 | 459 | * Returns true if the pin is enabled |
lucasec | 0:350d308e7b77 | 460 | */ |
lucasec | 0:350d308e7b77 | 461 | bool isAnalogEnabled(uint8_t pin); |
lucasec | 0:350d308e7b77 | 462 | /** |
lucasec | 0:350d308e7b77 | 463 | * Returns true if the pin is enabled |
lucasec | 0:350d308e7b77 | 464 | */ |
lucasec | 0:350d308e7b77 | 465 | bool isDigitalEnabled(uint8_t pin); |
lucasec | 0:350d308e7b77 | 466 | /** |
lucasec | 0:350d308e7b77 | 467 | * Returns the 10-bit analog reading of the specified pin. |
lucasec | 0:350d308e7b77 | 468 | * Valid pins include ADC:xxx. |
lucasec | 0:350d308e7b77 | 469 | */ |
lucasec | 0:350d308e7b77 | 470 | uint16_t getAnalog(uint8_t pin); |
lucasec | 0:350d308e7b77 | 471 | /** |
lucasec | 0:350d308e7b77 | 472 | * Returns true if the specified pin is high/on. |
lucasec | 0:350d308e7b77 | 473 | * Valid pins include DIO:xxx. |
lucasec | 0:350d308e7b77 | 474 | */ |
lucasec | 0:350d308e7b77 | 475 | bool isDigitalOn(uint8_t pin); |
lucasec | 0:350d308e7b77 | 476 | uint8_t getDigitalMaskMsb(); |
lucasec | 0:350d308e7b77 | 477 | uint8_t getDigitalMaskLsb(); |
lucasec | 0:350d308e7b77 | 478 | uint8_t getAnalogMask(); |
lucasec | 0:350d308e7b77 | 479 | |
lucasec | 0:350d308e7b77 | 480 | static const uint8_t API_ID = ZB_IO_SAMPLE_RESPONSE; |
lucasec | 0:350d308e7b77 | 481 | }; |
lucasec | 0:350d308e7b77 | 482 | |
lucasec | 0:350d308e7b77 | 483 | #endif |
lucasec | 0:350d308e7b77 | 484 | |
lucasec | 0:350d308e7b77 | 485 | #ifdef SERIES_1 |
lucasec | 0:350d308e7b77 | 486 | /** |
lucasec | 0:350d308e7b77 | 487 | * Represents a Series 1 TX Status packet |
lucasec | 0:350d308e7b77 | 488 | */ |
lucasec | 0:350d308e7b77 | 489 | class TxStatusResponse : public FrameIdResponse { |
lucasec | 0:350d308e7b77 | 490 | public: |
lucasec | 0:350d308e7b77 | 491 | TxStatusResponse(); |
lucasec | 0:350d308e7b77 | 492 | uint8_t getStatus(); |
lucasec | 0:350d308e7b77 | 493 | bool isSuccess(); |
lucasec | 0:350d308e7b77 | 494 | |
lucasec | 0:350d308e7b77 | 495 | static const uint8_t API_ID = TX_STATUS_RESPONSE; |
lucasec | 0:350d308e7b77 | 496 | }; |
lucasec | 0:350d308e7b77 | 497 | |
lucasec | 0:350d308e7b77 | 498 | /** |
lucasec | 0:350d308e7b77 | 499 | * Represents a Series 1 RX packet |
lucasec | 0:350d308e7b77 | 500 | */ |
lucasec | 0:350d308e7b77 | 501 | class RxResponse : public RxDataResponse { |
lucasec | 0:350d308e7b77 | 502 | public: |
lucasec | 0:350d308e7b77 | 503 | RxResponse(); |
lucasec | 0:350d308e7b77 | 504 | // remember rssi is negative but this is unsigned byte so it's up to you to convert |
lucasec | 0:350d308e7b77 | 505 | uint8_t getRssi(); |
lucasec | 0:350d308e7b77 | 506 | uint8_t getOption(); |
lucasec | 0:350d308e7b77 | 507 | bool isAddressBroadcast(); |
lucasec | 0:350d308e7b77 | 508 | bool isPanBroadcast(); |
lucasec | 0:350d308e7b77 | 509 | virtual uint8_t getDataLength(); |
lucasec | 0:350d308e7b77 | 510 | virtual uint8_t getDataOffset(); |
lucasec | 0:350d308e7b77 | 511 | virtual uint8_t getRssiOffset() = 0; |
lucasec | 0:350d308e7b77 | 512 | }; |
lucasec | 0:350d308e7b77 | 513 | |
lucasec | 0:350d308e7b77 | 514 | /** |
lucasec | 0:350d308e7b77 | 515 | * Represents a Series 1 16-bit address RX packet |
lucasec | 0:350d308e7b77 | 516 | */ |
lucasec | 0:350d308e7b77 | 517 | class Rx16Response : public RxResponse { |
lucasec | 0:350d308e7b77 | 518 | public: |
lucasec | 0:350d308e7b77 | 519 | Rx16Response(); |
lucasec | 0:350d308e7b77 | 520 | virtual uint8_t getRssiOffset(); |
lucasec | 0:350d308e7b77 | 521 | uint16_t getRemoteAddress16(); |
lucasec | 0:350d308e7b77 | 522 | |
lucasec | 0:350d308e7b77 | 523 | static const uint8_t API_ID = RX_16_RESPONSE; |
lucasec | 0:350d308e7b77 | 524 | protected: |
lucasec | 0:350d308e7b77 | 525 | uint16_t _remoteAddress; |
lucasec | 0:350d308e7b77 | 526 | }; |
lucasec | 0:350d308e7b77 | 527 | |
lucasec | 0:350d308e7b77 | 528 | /** |
lucasec | 0:350d308e7b77 | 529 | * Represents a Series 1 64-bit address RX packet |
lucasec | 0:350d308e7b77 | 530 | */ |
lucasec | 0:350d308e7b77 | 531 | class Rx64Response : public RxResponse { |
lucasec | 0:350d308e7b77 | 532 | public: |
lucasec | 0:350d308e7b77 | 533 | Rx64Response(); |
lucasec | 0:350d308e7b77 | 534 | virtual uint8_t getRssiOffset(); |
lucasec | 0:350d308e7b77 | 535 | XBeeAddress64& getRemoteAddress64(); |
lucasec | 0:350d308e7b77 | 536 | |
lucasec | 0:350d308e7b77 | 537 | static const uint8_t API_ID = RX_64_RESPONSE; |
lucasec | 0:350d308e7b77 | 538 | private: |
lucasec | 0:350d308e7b77 | 539 | XBeeAddress64 _remoteAddress; |
lucasec | 0:350d308e7b77 | 540 | }; |
lucasec | 0:350d308e7b77 | 541 | |
lucasec | 0:350d308e7b77 | 542 | /** |
lucasec | 0:350d308e7b77 | 543 | * Represents a Series 1 RX I/O Sample packet |
lucasec | 0:350d308e7b77 | 544 | */ |
lucasec | 0:350d308e7b77 | 545 | class RxIoSampleBaseResponse : public RxResponse { |
lucasec | 0:350d308e7b77 | 546 | public: |
lucasec | 0:350d308e7b77 | 547 | RxIoSampleBaseResponse(); |
lucasec | 0:350d308e7b77 | 548 | /** |
lucasec | 0:350d308e7b77 | 549 | * Returns the number of samples in this packet |
lucasec | 0:350d308e7b77 | 550 | */ |
lucasec | 0:350d308e7b77 | 551 | uint8_t getSampleSize(); |
lucasec | 0:350d308e7b77 | 552 | bool containsAnalog(); |
lucasec | 0:350d308e7b77 | 553 | bool containsDigital(); |
lucasec | 0:350d308e7b77 | 554 | /** |
lucasec | 0:350d308e7b77 | 555 | * Returns true if the specified analog pin is enabled |
lucasec | 0:350d308e7b77 | 556 | */ |
lucasec | 0:350d308e7b77 | 557 | bool isAnalogEnabled(uint8_t pin); |
lucasec | 0:350d308e7b77 | 558 | /** |
lucasec | 0:350d308e7b77 | 559 | * Returns true if the specified digital pin is enabled |
lucasec | 0:350d308e7b77 | 560 | */ |
lucasec | 0:350d308e7b77 | 561 | bool isDigitalEnabled(uint8_t pin); |
lucasec | 0:350d308e7b77 | 562 | /** |
lucasec | 0:350d308e7b77 | 563 | * Returns the 10-bit analog reading of the specified pin. |
lucasec | 0:350d308e7b77 | 564 | * Valid pins include ADC:0-5. Sample index starts at 0 |
lucasec | 0:350d308e7b77 | 565 | */ |
lucasec | 0:350d308e7b77 | 566 | uint16_t getAnalog(uint8_t pin, uint8_t sample); |
lucasec | 0:350d308e7b77 | 567 | /** |
lucasec | 0:350d308e7b77 | 568 | * Returns true if the specified pin is high/on. |
lucasec | 0:350d308e7b77 | 569 | * Valid pins include DIO:0-8. Sample index starts at 0 |
lucasec | 0:350d308e7b77 | 570 | */ |
lucasec | 0:350d308e7b77 | 571 | bool isDigitalOn(uint8_t pin, uint8_t sample); |
lucasec | 0:350d308e7b77 | 572 | uint8_t getSampleOffset(); |
lucasec | 0:350d308e7b77 | 573 | |
lucasec | 0:350d308e7b77 | 574 | /** |
lucasec | 0:350d308e7b77 | 575 | * Gets the offset of the start of the given sample. |
lucasec | 0:350d308e7b77 | 576 | */ |
lucasec | 0:350d308e7b77 | 577 | uint8_t getSampleStart(uint8_t sample); |
lucasec | 0:350d308e7b77 | 578 | private: |
lucasec | 0:350d308e7b77 | 579 | }; |
lucasec | 0:350d308e7b77 | 580 | |
lucasec | 0:350d308e7b77 | 581 | class Rx16IoSampleResponse : public RxIoSampleBaseResponse { |
lucasec | 0:350d308e7b77 | 582 | public: |
lucasec | 0:350d308e7b77 | 583 | Rx16IoSampleResponse(); |
lucasec | 0:350d308e7b77 | 584 | uint16_t getRemoteAddress16(); |
lucasec | 0:350d308e7b77 | 585 | virtual uint8_t getRssiOffset(); |
lucasec | 0:350d308e7b77 | 586 | |
lucasec | 0:350d308e7b77 | 587 | static const uint8_t API_ID = RX_16_IO_RESPONSE; |
lucasec | 0:350d308e7b77 | 588 | }; |
lucasec | 0:350d308e7b77 | 589 | |
lucasec | 0:350d308e7b77 | 590 | class Rx64IoSampleResponse : public RxIoSampleBaseResponse { |
lucasec | 0:350d308e7b77 | 591 | public: |
lucasec | 0:350d308e7b77 | 592 | Rx64IoSampleResponse(); |
lucasec | 0:350d308e7b77 | 593 | XBeeAddress64& getRemoteAddress64(); |
lucasec | 0:350d308e7b77 | 594 | virtual uint8_t getRssiOffset(); |
lucasec | 0:350d308e7b77 | 595 | |
lucasec | 0:350d308e7b77 | 596 | static const uint8_t API_ID = RX_64_IO_RESPONSE; |
lucasec | 0:350d308e7b77 | 597 | private: |
lucasec | 0:350d308e7b77 | 598 | XBeeAddress64 _remoteAddress; |
lucasec | 0:350d308e7b77 | 599 | }; |
lucasec | 0:350d308e7b77 | 600 | |
lucasec | 0:350d308e7b77 | 601 | #endif |
lucasec | 0:350d308e7b77 | 602 | |
lucasec | 0:350d308e7b77 | 603 | /** |
lucasec | 0:350d308e7b77 | 604 | * Represents a Modem Status RX packet |
lucasec | 0:350d308e7b77 | 605 | */ |
lucasec | 0:350d308e7b77 | 606 | class ModemStatusResponse : public XBeeResponse { |
lucasec | 0:350d308e7b77 | 607 | public: |
lucasec | 0:350d308e7b77 | 608 | ModemStatusResponse(); |
lucasec | 0:350d308e7b77 | 609 | uint8_t getStatus(); |
lucasec | 0:350d308e7b77 | 610 | |
lucasec | 0:350d308e7b77 | 611 | static const uint8_t API_ID = MODEM_STATUS_RESPONSE; |
lucasec | 0:350d308e7b77 | 612 | }; |
lucasec | 0:350d308e7b77 | 613 | |
lucasec | 0:350d308e7b77 | 614 | /** |
lucasec | 0:350d308e7b77 | 615 | * Represents an AT Command RX packet |
lucasec | 0:350d308e7b77 | 616 | */ |
lucasec | 0:350d308e7b77 | 617 | class AtCommandResponse : public FrameIdResponse { |
lucasec | 0:350d308e7b77 | 618 | public: |
lucasec | 0:350d308e7b77 | 619 | AtCommandResponse(); |
lucasec | 0:350d308e7b77 | 620 | /** |
lucasec | 0:350d308e7b77 | 621 | * Returns an array containing the two character command |
lucasec | 0:350d308e7b77 | 622 | */ |
lucasec | 0:350d308e7b77 | 623 | uint8_t* getCommand(); |
lucasec | 0:350d308e7b77 | 624 | /** |
lucasec | 0:350d308e7b77 | 625 | * Returns the command status code. |
lucasec | 0:350d308e7b77 | 626 | * Zero represents a successful command |
lucasec | 0:350d308e7b77 | 627 | */ |
lucasec | 0:350d308e7b77 | 628 | uint8_t getStatus(); |
lucasec | 0:350d308e7b77 | 629 | /** |
lucasec | 0:350d308e7b77 | 630 | * Returns an array containing the command value. |
lucasec | 0:350d308e7b77 | 631 | * This is only applicable to query commands. |
lucasec | 0:350d308e7b77 | 632 | */ |
lucasec | 0:350d308e7b77 | 633 | uint8_t* getValue(); |
lucasec | 0:350d308e7b77 | 634 | /** |
lucasec | 0:350d308e7b77 | 635 | * Returns the length of the command value array. |
lucasec | 0:350d308e7b77 | 636 | */ |
lucasec | 0:350d308e7b77 | 637 | uint8_t getValueLength(); |
lucasec | 0:350d308e7b77 | 638 | /** |
lucasec | 0:350d308e7b77 | 639 | * Returns true if status equals AT_OK |
lucasec | 0:350d308e7b77 | 640 | */ |
lucasec | 0:350d308e7b77 | 641 | bool isOk(); |
lucasec | 0:350d308e7b77 | 642 | |
lucasec | 0:350d308e7b77 | 643 | static const uint8_t API_ID = AT_COMMAND_RESPONSE; |
lucasec | 0:350d308e7b77 | 644 | }; |
lucasec | 0:350d308e7b77 | 645 | |
lucasec | 0:350d308e7b77 | 646 | /** |
lucasec | 0:350d308e7b77 | 647 | * Represents a Remote AT Command RX packet |
lucasec | 0:350d308e7b77 | 648 | */ |
lucasec | 0:350d308e7b77 | 649 | class RemoteAtCommandResponse : public AtCommandResponse { |
lucasec | 0:350d308e7b77 | 650 | public: |
lucasec | 0:350d308e7b77 | 651 | RemoteAtCommandResponse(); |
lucasec | 0:350d308e7b77 | 652 | /** |
lucasec | 0:350d308e7b77 | 653 | * Returns an array containing the two character command |
lucasec | 0:350d308e7b77 | 654 | */ |
lucasec | 0:350d308e7b77 | 655 | uint8_t* getCommand(); |
lucasec | 0:350d308e7b77 | 656 | /** |
lucasec | 0:350d308e7b77 | 657 | * Returns the command status code. |
lucasec | 0:350d308e7b77 | 658 | * Zero represents a successful command |
lucasec | 0:350d308e7b77 | 659 | */ |
lucasec | 0:350d308e7b77 | 660 | uint8_t getStatus(); |
lucasec | 0:350d308e7b77 | 661 | /** |
lucasec | 0:350d308e7b77 | 662 | * Returns an array containing the command value. |
lucasec | 0:350d308e7b77 | 663 | * This is only applicable to query commands. |
lucasec | 0:350d308e7b77 | 664 | */ |
lucasec | 0:350d308e7b77 | 665 | uint8_t* getValue(); |
lucasec | 0:350d308e7b77 | 666 | /** |
lucasec | 0:350d308e7b77 | 667 | * Returns the length of the command value array. |
lucasec | 0:350d308e7b77 | 668 | */ |
lucasec | 0:350d308e7b77 | 669 | uint8_t getValueLength(); |
lucasec | 0:350d308e7b77 | 670 | /** |
lucasec | 0:350d308e7b77 | 671 | * Returns the 16-bit address of the remote radio |
lucasec | 0:350d308e7b77 | 672 | */ |
lucasec | 0:350d308e7b77 | 673 | uint16_t getRemoteAddress16(); |
lucasec | 0:350d308e7b77 | 674 | /** |
lucasec | 0:350d308e7b77 | 675 | * Returns the 64-bit address of the remote radio |
lucasec | 0:350d308e7b77 | 676 | */ |
lucasec | 0:350d308e7b77 | 677 | XBeeAddress64& getRemoteAddress64(); |
lucasec | 0:350d308e7b77 | 678 | /** |
lucasec | 0:350d308e7b77 | 679 | * Returns true if command was successful |
lucasec | 0:350d308e7b77 | 680 | */ |
lucasec | 0:350d308e7b77 | 681 | bool isOk(); |
lucasec | 0:350d308e7b77 | 682 | |
lucasec | 0:350d308e7b77 | 683 | static const uint8_t API_ID = REMOTE_AT_COMMAND_RESPONSE; |
lucasec | 0:350d308e7b77 | 684 | private: |
lucasec | 0:350d308e7b77 | 685 | XBeeAddress64 _remoteAddress64; |
lucasec | 0:350d308e7b77 | 686 | }; |
lucasec | 0:350d308e7b77 | 687 | |
lucasec | 0:350d308e7b77 | 688 | |
lucasec | 0:350d308e7b77 | 689 | /** |
lucasec | 0:350d308e7b77 | 690 | * Super class of all XBee requests (TX packets) |
lucasec | 0:350d308e7b77 | 691 | * Users should never create an instance of this class; instead use an subclass of this class |
lucasec | 0:350d308e7b77 | 692 | * It is recommended to reuse Subclasses of the class to conserve memory |
lucasec | 0:350d308e7b77 | 693 | * <p/> |
lucasec | 0:350d308e7b77 | 694 | * This class allocates a buffer to |
lucasec | 0:350d308e7b77 | 695 | */ |
lucasec | 0:350d308e7b77 | 696 | class XBeeRequest { |
lucasec | 0:350d308e7b77 | 697 | public: |
lucasec | 0:350d308e7b77 | 698 | /** |
lucasec | 0:350d308e7b77 | 699 | * Constructor |
lucasec | 0:350d308e7b77 | 700 | * TODO make protected |
lucasec | 0:350d308e7b77 | 701 | */ |
lucasec | 0:350d308e7b77 | 702 | XBeeRequest(uint8_t apiId, uint8_t frameId); |
lucasec | 0:350d308e7b77 | 703 | /** |
lucasec | 0:350d308e7b77 | 704 | * Sets the frame id. Must be between 1 and 255 inclusive to get a TX status response. |
lucasec | 0:350d308e7b77 | 705 | */ |
lucasec | 0:350d308e7b77 | 706 | void setFrameId(uint8_t frameId); |
lucasec | 0:350d308e7b77 | 707 | /** |
lucasec | 0:350d308e7b77 | 708 | * Returns the frame id |
lucasec | 0:350d308e7b77 | 709 | */ |
lucasec | 0:350d308e7b77 | 710 | uint8_t getFrameId(); |
lucasec | 0:350d308e7b77 | 711 | /** |
lucasec | 0:350d308e7b77 | 712 | * Returns the API id |
lucasec | 0:350d308e7b77 | 713 | */ |
lucasec | 0:350d308e7b77 | 714 | uint8_t getApiId(); |
lucasec | 0:350d308e7b77 | 715 | // setting = 0 makes this a pure virtual function, meaning the subclass must implement, like abstract in java |
lucasec | 0:350d308e7b77 | 716 | /** |
lucasec | 0:350d308e7b77 | 717 | * Starting after the frame id (pos = 0) and up to but not including the checksum |
lucasec | 0:350d308e7b77 | 718 | * Note: Unlike Digi's definition of the frame data, this does not start with the API ID. |
lucasec | 0:350d308e7b77 | 719 | * The reason for this is the API ID and Frame ID are common to all requests, whereas my definition of |
lucasec | 0:350d308e7b77 | 720 | * frame data is only the API specific data. |
lucasec | 0:350d308e7b77 | 721 | */ |
lucasec | 0:350d308e7b77 | 722 | virtual uint8_t getFrameData(uint8_t pos) = 0; |
lucasec | 0:350d308e7b77 | 723 | /** |
lucasec | 0:350d308e7b77 | 724 | * Returns the size of the api frame (not including frame id or api id or checksum). |
lucasec | 0:350d308e7b77 | 725 | */ |
lucasec | 0:350d308e7b77 | 726 | virtual uint8_t getFrameDataLength() = 0; |
lucasec | 0:350d308e7b77 | 727 | //void reset(); |
lucasec | 0:350d308e7b77 | 728 | protected: |
lucasec | 0:350d308e7b77 | 729 | void setApiId(uint8_t apiId); |
lucasec | 0:350d308e7b77 | 730 | private: |
lucasec | 0:350d308e7b77 | 731 | uint8_t _apiId; |
lucasec | 0:350d308e7b77 | 732 | uint8_t _frameId; |
lucasec | 0:350d308e7b77 | 733 | }; |
lucasec | 0:350d308e7b77 | 734 | |
lucasec | 0:350d308e7b77 | 735 | // TODO add reset/clear method since responses are often reused |
lucasec | 0:350d308e7b77 | 736 | /** |
lucasec | 0:350d308e7b77 | 737 | * Primary interface for communicating with an XBee Radio. |
lucasec | 0:350d308e7b77 | 738 | * This class provides methods for sending and receiving packets with an XBee radio via the serial port. |
lucasec | 0:350d308e7b77 | 739 | * The XBee radio must be configured in API (packet) mode (AP=2) |
lucasec | 0:350d308e7b77 | 740 | * in order to use this software. |
lucasec | 0:350d308e7b77 | 741 | * <p/> |
lucasec | 0:350d308e7b77 | 742 | * Since this code is designed to run on a microcontroller, with only one thread, you are responsible for reading the |
lucasec | 0:350d308e7b77 | 743 | * data off the serial buffer in a timely manner. This involves a call to a variant of readPacket(...). |
lucasec | 0:350d308e7b77 | 744 | * If your serial port is receiving data faster than you are reading, you can expect to lose packets. |
lucasec | 0:350d308e7b77 | 745 | * Arduino only has a 128 byte serial buffer so it can easily overflow if two or more packets arrive |
lucasec | 0:350d308e7b77 | 746 | * without a call to readPacket(...) |
lucasec | 0:350d308e7b77 | 747 | * <p/> |
lucasec | 0:350d308e7b77 | 748 | * In order to conserve resources, this class only supports storing one response packet in memory at a time. |
lucasec | 0:350d308e7b77 | 749 | * This means that you must fully consume the packet prior to calling readPacket(...), because calling |
lucasec | 0:350d308e7b77 | 750 | * readPacket(...) overwrites the previous response. |
lucasec | 0:350d308e7b77 | 751 | * <p/> |
lucasec | 0:350d308e7b77 | 752 | * This class creates an array of size MAX_FRAME_DATA_SIZE for storing the response packet. You may want |
lucasec | 0:350d308e7b77 | 753 | * to adjust this value to conserve memory. |
lucasec | 0:350d308e7b77 | 754 | * |
lucasec | 0:350d308e7b77 | 755 | * \author Andrew Rapp |
lucasec | 0:350d308e7b77 | 756 | */ |
lucasec | 0:350d308e7b77 | 757 | class XBee { |
lucasec | 0:350d308e7b77 | 758 | public: |
lucasec | 0:350d308e7b77 | 759 | XBee(RawSerial &serial); |
lucasec | 0:350d308e7b77 | 760 | /** |
lucasec | 0:350d308e7b77 | 761 | * Reads all available serial bytes until a packet is parsed, an error occurs, or the buffer is empty. |
lucasec | 0:350d308e7b77 | 762 | * You may call <i>xbee</i>.getResponse().isAvailable() after calling this method to determine if |
lucasec | 0:350d308e7b77 | 763 | * a packet is ready, or <i>xbee</i>.getResponse().isError() to determine if |
lucasec | 0:350d308e7b77 | 764 | * a error occurred. |
lucasec | 0:350d308e7b77 | 765 | * <p/> |
lucasec | 0:350d308e7b77 | 766 | * This method should always return quickly since it does not wait for serial data to arrive. |
lucasec | 0:350d308e7b77 | 767 | * You will want to use this method if you are doing other timely stuff in your loop, where |
lucasec | 0:350d308e7b77 | 768 | * a delay would cause problems. |
lucasec | 0:350d308e7b77 | 769 | * NOTE: calling this method resets the current response, so make sure you first consume the |
lucasec | 0:350d308e7b77 | 770 | * current response |
lucasec | 0:350d308e7b77 | 771 | */ |
lucasec | 0:350d308e7b77 | 772 | void readPacket(); |
lucasec | 0:350d308e7b77 | 773 | /** |
lucasec | 0:350d308e7b77 | 774 | * Waits a maximum of <i>timeout</i> milliseconds for a response packet before timing out; returns true if packet is read. |
lucasec | 0:350d308e7b77 | 775 | * Returns false if timeout or error occurs. |
lucasec | 0:350d308e7b77 | 776 | */ |
lucasec | 0:350d308e7b77 | 777 | bool readPacket(int timeout); |
lucasec | 0:350d308e7b77 | 778 | /** |
lucasec | 0:350d308e7b77 | 779 | * Reads until a packet is received or an error occurs. |
lucasec | 0:350d308e7b77 | 780 | * Caution: use this carefully since if you don't get a response, your Arduino code will hang on this |
lucasec | 0:350d308e7b77 | 781 | * call forever!! often it's better to use a timeout: readPacket(int) |
lucasec | 0:350d308e7b77 | 782 | */ |
lucasec | 0:350d308e7b77 | 783 | void readPacketUntilAvailable(); |
lucasec | 0:350d308e7b77 | 784 | |
lucasec | 0:350d308e7b77 | 785 | void getResponse(XBeeResponse &response); |
lucasec | 0:350d308e7b77 | 786 | /** |
lucasec | 0:350d308e7b77 | 787 | * Returns a reference to the current response |
lucasec | 0:350d308e7b77 | 788 | * Note: once readPacket is called again this response will be overwritten! |
lucasec | 0:350d308e7b77 | 789 | */ |
lucasec | 0:350d308e7b77 | 790 | XBeeResponse& getResponse(); |
lucasec | 0:350d308e7b77 | 791 | /** |
lucasec | 0:350d308e7b77 | 792 | * Sends a XBeeRequest (TX packet) out the serial port |
lucasec | 0:350d308e7b77 | 793 | */ |
lucasec | 0:350d308e7b77 | 794 | void send(XBeeRequest &request); |
lucasec | 0:350d308e7b77 | 795 | //uint8_t sendAndWaitForResponse(XBeeRequest &request, int timeout); |
lucasec | 0:350d308e7b77 | 796 | /** |
lucasec | 0:350d308e7b77 | 797 | * Returns a sequential frame id between 1 and 255 |
lucasec | 0:350d308e7b77 | 798 | */ |
lucasec | 0:350d308e7b77 | 799 | uint8_t getNextFrameId(); |
lucasec | 0:350d308e7b77 | 800 | /** |
lucasec | 0:350d308e7b77 | 801 | * Specify the serial port. |
lucasec | 0:350d308e7b77 | 802 | */ |
lucasec | 0:350d308e7b77 | 803 | void setSerial(RawSerial &serial); |
lucasec | 0:350d308e7b77 | 804 | protected: |
lucasec | 0:350d308e7b77 | 805 | Timer timer; |
lucasec | 0:350d308e7b77 | 806 | private: |
lucasec | 0:350d308e7b77 | 807 | bool available(); |
lucasec | 0:350d308e7b77 | 808 | uint8_t read(); |
lucasec | 0:350d308e7b77 | 809 | void flush(); |
lucasec | 0:350d308e7b77 | 810 | void write(uint8_t val); |
lucasec | 0:350d308e7b77 | 811 | void sendByte(uint8_t b, bool escape); |
lucasec | 0:350d308e7b77 | 812 | void resetResponse(); |
lucasec | 0:350d308e7b77 | 813 | XBeeResponse _response; |
lucasec | 0:350d308e7b77 | 814 | bool _escape; |
lucasec | 0:350d308e7b77 | 815 | // current packet position for response. just a state variable for packet parsing and has no relevance for the response otherwise |
lucasec | 0:350d308e7b77 | 816 | uint8_t _pos; |
lucasec | 0:350d308e7b77 | 817 | // last byte read |
lucasec | 0:350d308e7b77 | 818 | uint8_t b; |
lucasec | 0:350d308e7b77 | 819 | uint8_t _checksumTotal; |
lucasec | 0:350d308e7b77 | 820 | uint8_t _nextFrameId; |
lucasec | 0:350d308e7b77 | 821 | // buffer for incoming RX packets. holds only the api specific frame data, starting after the api id byte and prior to checksum |
lucasec | 0:350d308e7b77 | 822 | uint8_t _responseFrameData[MAX_FRAME_DATA_SIZE]; |
lucasec | 0:350d308e7b77 | 823 | RawSerial* _serial; |
lucasec | 0:350d308e7b77 | 824 | }; |
lucasec | 0:350d308e7b77 | 825 | |
lucasec | 0:350d308e7b77 | 826 | |
lucasec | 0:350d308e7b77 | 827 | /** |
lucasec | 0:350d308e7b77 | 828 | * This class can be used instead of the XBee class and allows |
lucasec | 0:350d308e7b77 | 829 | * user-specified callback functions to be called when responses are |
lucasec | 0:350d308e7b77 | 830 | * received, simplifying the processing code and reducing boilerplate. |
lucasec | 0:350d308e7b77 | 831 | * |
lucasec | 0:350d308e7b77 | 832 | * To use it, first register your callback functions using the onXxx |
lucasec | 0:350d308e7b77 | 833 | * methods. Each method has a uintptr_t data argument, that can be used to |
lucasec | 0:350d308e7b77 | 834 | * pass arbitrary data to the callback (useful when using the same |
lucasec | 0:350d308e7b77 | 835 | * function for multiple callbacks, or have a generic function that can |
lucasec | 0:350d308e7b77 | 836 | * behave differently in different circumstances). Supplying the data |
lucasec | 0:350d308e7b77 | 837 | * parameter is optional, but the callback must always accept it (just |
lucasec | 0:350d308e7b77 | 838 | * ignore it if it's unused). The uintptr_t type is an integer type |
lucasec | 0:350d308e7b77 | 839 | * guaranteed to be big enough to fit a pointer (it is 16-bit on AVR, |
lucasec | 0:350d308e7b77 | 840 | * 32-bit on ARM), so it can also be used to store a pointer to access |
lucasec | 0:350d308e7b77 | 841 | * more data if required (using proper casts). |
lucasec | 0:350d308e7b77 | 842 | * |
lucasec | 0:350d308e7b77 | 843 | * There can be only one callback of each type registered at one time, |
lucasec | 0:350d308e7b77 | 844 | * so registering callback overwrites any previously registered one. To |
lucasec | 0:350d308e7b77 | 845 | * unregister a callback, pass NULL as the function. |
lucasec | 0:350d308e7b77 | 846 | * |
lucasec | 0:350d308e7b77 | 847 | * To ensure that the callbacks are actually called, call the loop() |
lucasec | 0:350d308e7b77 | 848 | * method regularly (in your loop() function, for example). This takes |
lucasec | 0:350d308e7b77 | 849 | * care of calling readPacket() and getResponse() other methods on the |
lucasec | 0:350d308e7b77 | 850 | * XBee class, so there is no need to do so directly (though it should |
lucasec | 0:350d308e7b77 | 851 | * not mess with this class if you do, it would only mean some callbacks |
lucasec | 0:350d308e7b77 | 852 | * aren't called). |
lucasec | 0:350d308e7b77 | 853 | * |
lucasec | 0:350d308e7b77 | 854 | * Inside callbacks, you should generally not be blocking / waiting. |
lucasec | 0:350d308e7b77 | 855 | * Since callbacks can be called from inside waitFor() and friends, a |
lucasec | 0:350d308e7b77 | 856 | * callback that doesn't return quickly can mess up the waitFor() |
lucasec | 0:350d308e7b77 | 857 | * timeout. |
lucasec | 0:350d308e7b77 | 858 | * |
lucasec | 0:350d308e7b77 | 859 | * Sending packets is not a problem inside a callback, but avoid |
lucasec | 0:350d308e7b77 | 860 | * receiving a packet (e.g. calling readPacket(), loop() or waitFor() |
lucasec | 0:350d308e7b77 | 861 | * and friends) inside a callback (since that would overwrite the |
lucasec | 0:350d308e7b77 | 862 | * current response, messing up any pending callbacks and waitFor() etc. |
lucasec | 0:350d308e7b77 | 863 | * methods already running). |
lucasec | 0:350d308e7b77 | 864 | */ |
lucasec | 0:350d308e7b77 | 865 | class XBeeWithCallbacks : public XBee { |
lucasec | 0:350d308e7b77 | 866 | public: |
lucasec | 0:350d308e7b77 | 867 | |
lucasec | 0:350d308e7b77 | 868 | /** |
lucasec | 0:350d308e7b77 | 869 | * Register a packet error callback. It is called whenever an |
lucasec | 0:350d308e7b77 | 870 | * error occurs in the packet reading process. Arguments to the |
lucasec | 0:350d308e7b77 | 871 | * callback will be the error code (as returned by |
lucasec | 0:350d308e7b77 | 872 | * XBeeResponse::getErrorCode()) and the data parameter. while |
lucasec | 0:350d308e7b77 | 873 | * registering the callback. |
lucasec | 0:350d308e7b77 | 874 | */ |
lucasec | 0:350d308e7b77 | 875 | void onPacketError(void (*func)(uint8_t, uintptr_t), uintptr_t data = 0) { _onPacketError.set(func, data); } |
lucasec | 0:350d308e7b77 | 876 | |
lucasec | 0:350d308e7b77 | 877 | /** |
lucasec | 0:350d308e7b77 | 878 | * Register a response received callback. It is called whenever |
lucasec | 0:350d308e7b77 | 879 | * a response was succesfully received, before a response |
lucasec | 0:350d308e7b77 | 880 | * specific callback (or onOtherResponse) below is called. |
lucasec | 0:350d308e7b77 | 881 | * |
lucasec | 0:350d308e7b77 | 882 | * Arguments to the callback will be the received response and |
lucasec | 0:350d308e7b77 | 883 | * the data parameter passed while registering the callback. |
lucasec | 0:350d308e7b77 | 884 | */ |
lucasec | 0:350d308e7b77 | 885 | void onResponse(void (*func)(XBeeResponse&, uintptr_t), uintptr_t data = 0) { _onResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 886 | |
lucasec | 0:350d308e7b77 | 887 | /** |
lucasec | 0:350d308e7b77 | 888 | * Register an other response received callback. It is called |
lucasec | 0:350d308e7b77 | 889 | * whenever a response was succesfully received, but no response |
lucasec | 0:350d308e7b77 | 890 | * specific callback was registered using the functions below |
lucasec | 0:350d308e7b77 | 891 | * (after the onResponse callback is called). |
lucasec | 0:350d308e7b77 | 892 | * |
lucasec | 0:350d308e7b77 | 893 | * Arguments to the callback will be the received response and |
lucasec | 0:350d308e7b77 | 894 | * the data parameter passed while registering the callback. |
lucasec | 0:350d308e7b77 | 895 | */ |
lucasec | 0:350d308e7b77 | 896 | void onOtherResponse(void (*func)(XBeeResponse&, uintptr_t), uintptr_t data = 0) { _onOtherResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 897 | |
lucasec | 0:350d308e7b77 | 898 | // These functions register a response specific callback. They |
lucasec | 0:350d308e7b77 | 899 | // are called whenever a response of the appropriate type was |
lucasec | 0:350d308e7b77 | 900 | // succesfully received (after the onResponse callback is |
lucasec | 0:350d308e7b77 | 901 | // called). |
lucasec | 0:350d308e7b77 | 902 | // |
lucasec | 0:350d308e7b77 | 903 | // Arguments to the callback will be the received response |
lucasec | 0:350d308e7b77 | 904 | // (already converted to the appropriate type) and the data |
lucasec | 0:350d308e7b77 | 905 | // parameter passed while registering the callback. |
lucasec | 0:350d308e7b77 | 906 | void onZBTxStatusResponse(void (*func)(ZBTxStatusResponse&, uintptr_t), uintptr_t data = 0) { _onZBTxStatusResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 907 | void onZBRxResponse(void (*func)(ZBRxResponse&, uintptr_t), uintptr_t data = 0) { _onZBRxResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 908 | void onZBExplicitRxResponse(void (*func)(ZBExplicitRxResponse&, uintptr_t), uintptr_t data = 0) { _onZBExplicitRxResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 909 | void onZBRxIoSampleResponse(void (*func)(ZBRxIoSampleResponse&, uintptr_t), uintptr_t data = 0) { _onZBRxIoSampleResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 910 | void onTxStatusResponse(void (*func)(TxStatusResponse&, uintptr_t), uintptr_t data = 0) { _onTxStatusResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 911 | void onRx16Response(void (*func)(Rx16Response&, uintptr_t), uintptr_t data = 0) { _onRx16Response.set(func, data); } |
lucasec | 0:350d308e7b77 | 912 | void onRx64Response(void (*func)(Rx64Response&, uintptr_t), uintptr_t data = 0) { _onRx64Response.set(func, data); } |
lucasec | 0:350d308e7b77 | 913 | void onRx16IoSampleResponse(void (*func)(Rx16IoSampleResponse&, uintptr_t), uintptr_t data = 0) { _onRx16IoSampleResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 914 | void onRx64IoSampleResponse(void (*func)(Rx64IoSampleResponse&, uintptr_t), uintptr_t data = 0) { _onRx64IoSampleResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 915 | void onModemStatusResponse(void (*func)(ModemStatusResponse&, uintptr_t), uintptr_t data = 0) { _onModemStatusResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 916 | void onAtCommandResponse(void (*func)(AtCommandResponse&, uintptr_t), uintptr_t data = 0) { _onAtCommandResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 917 | void onRemoteAtCommandResponse(void (*func)(RemoteAtCommandResponse&, uintptr_t), uintptr_t data = 0) { _onRemoteAtCommandResponse.set(func, data); } |
lucasec | 0:350d308e7b77 | 918 | |
lucasec | 0:350d308e7b77 | 919 | /** |
lucasec | 0:350d308e7b77 | 920 | * Regularly call this method, which ensures that the serial |
lucasec | 0:350d308e7b77 | 921 | * buffer is processed and the appropriate callbacks are called. |
lucasec | 0:350d308e7b77 | 922 | */ |
lucasec | 0:350d308e7b77 | 923 | void loop(); |
lucasec | 0:350d308e7b77 | 924 | |
lucasec | 0:350d308e7b77 | 925 | /** |
lucasec | 0:350d308e7b77 | 926 | * Wait for a API response of the given type, optionally |
lucasec | 0:350d308e7b77 | 927 | * filtered by the given match function. |
lucasec | 0:350d308e7b77 | 928 | * |
lucasec | 0:350d308e7b77 | 929 | * If a match function is given it is called for every response |
lucasec | 0:350d308e7b77 | 930 | * of the right type received, passing the response and the data |
lucasec | 0:350d308e7b77 | 931 | * parameter passed to this method. If the function returns true |
lucasec | 0:350d308e7b77 | 932 | * (or if no function was passed), waiting stops and this method |
lucasec | 0:350d308e7b77 | 933 | * returns 0. If the function returns false, waiting |
lucasec | 0:350d308e7b77 | 934 | * continues. After the given timeout passes, this method |
lucasec | 0:350d308e7b77 | 935 | * returns XBEE_WAIT_TIMEOUT. |
lucasec | 0:350d308e7b77 | 936 | * |
lucasec | 0:350d308e7b77 | 937 | * If a valid frameId is passed (e.g. 0-255 inclusive) and a |
lucasec | 0:350d308e7b77 | 938 | * status API response frame is received while waiting, that has |
lucasec | 0:350d308e7b77 | 939 | * a *non-zero* status, waiting stops and that status is |
lucasec | 0:350d308e7b77 | 940 | * received. This is intended for when a TX packet was sent and |
lucasec | 0:350d308e7b77 | 941 | * you are waiting for an RX reply, which will most likely never |
lucasec | 0:350d308e7b77 | 942 | * arrive when TX failed. However, since the status reply is not |
lucasec | 0:350d308e7b77 | 943 | * guaranteed to arrive before the RX reply (a remote module can |
lucasec | 0:350d308e7b77 | 944 | * send a reply before the ACK), first calling waitForStatus() |
lucasec | 0:350d308e7b77 | 945 | * and then waitFor() can sometimes miss the reply RX packet. |
lucasec | 0:350d308e7b77 | 946 | * |
lucasec | 0:350d308e7b77 | 947 | * Note that when the intended response is received *before* the |
lucasec | 0:350d308e7b77 | 948 | * status reply, the latter will not be processed by this |
lucasec | 0:350d308e7b77 | 949 | * method and will be subsequently processed by e.g. loop() |
lucasec | 0:350d308e7b77 | 950 | * normally. |
lucasec | 0:350d308e7b77 | 951 | * |
lucasec | 0:350d308e7b77 | 952 | * While waiting, any other responses received are passed to the |
lucasec | 0:350d308e7b77 | 953 | * relevant callbacks, just as if calling loop() continuously |
lucasec | 0:350d308e7b77 | 954 | * (except for the response sought, that one is only passed to |
lucasec | 0:350d308e7b77 | 955 | * the OnResponse handler and no others). |
lucasec | 0:350d308e7b77 | 956 | * |
lucasec | 0:350d308e7b77 | 957 | * After this method returns, the response itself can still be |
lucasec | 0:350d308e7b77 | 958 | * retrieved using getResponse() as normal. |
lucasec | 0:350d308e7b77 | 959 | */ |
lucasec | 0:350d308e7b77 | 960 | template <typename Response> |
lucasec | 0:350d308e7b77 | 961 | uint8_t waitFor(Response& response, uint16_t timeout, bool (*func)(Response&, uintptr_t) = NULL, uintptr_t data = 0, int16_t frameId = -1) { |
lucasec | 0:350d308e7b77 | 962 | return waitForInternal(Response::API_ID, &response, timeout, (void*)func, data, frameId); |
lucasec | 0:350d308e7b77 | 963 | } |
lucasec | 0:350d308e7b77 | 964 | |
lucasec | 0:350d308e7b77 | 965 | /** |
lucasec | 0:350d308e7b77 | 966 | * Sends a XBeeRequest (TX packet) out the serial port, and wait |
lucasec | 0:350d308e7b77 | 967 | * for a status response API frame (up until the given timeout). |
lucasec | 0:350d308e7b77 | 968 | * Essentially this just calls send() and waitForStatus(). |
lucasec | 0:350d308e7b77 | 969 | * See waitForStatus for the meaning of the return value and |
lucasec | 0:350d308e7b77 | 970 | * more details. |
lucasec | 0:350d308e7b77 | 971 | */ |
lucasec | 0:350d308e7b77 | 972 | uint8_t sendAndWait(XBeeRequest &request, uint16_t timeout) { |
lucasec | 0:350d308e7b77 | 973 | send(request); |
lucasec | 0:350d308e7b77 | 974 | return waitForStatus(request.getFrameId(), timeout); |
lucasec | 0:350d308e7b77 | 975 | } |
lucasec | 0:350d308e7b77 | 976 | |
lucasec | 0:350d308e7b77 | 977 | /** |
lucasec | 0:350d308e7b77 | 978 | * Wait for a status API response with the given frameId and |
lucasec | 0:350d308e7b77 | 979 | * return the status from the packet (for ZB_TX_STATUS_RESPONSE, |
lucasec | 0:350d308e7b77 | 980 | * this returns just the delivery status, not the routing |
lucasec | 0:350d308e7b77 | 981 | * status). If the timeout is reached before reading the |
lucasec | 0:350d308e7b77 | 982 | * response, XBEE_WAIT_TIMEOUT is returned instead. |
lucasec | 0:350d308e7b77 | 983 | * |
lucasec | 0:350d308e7b77 | 984 | * While waiting, any other responses received are passed to the |
lucasec | 0:350d308e7b77 | 985 | * relevant callbacks, just as if calling loop() continuously |
lucasec | 0:350d308e7b77 | 986 | * (except for the status response sought, that one is only |
lucasec | 0:350d308e7b77 | 987 | * passed to the OnResponse handler and no others). |
lucasec | 0:350d308e7b77 | 988 | * |
lucasec | 0:350d308e7b77 | 989 | * After this method returns, the response itself can still be |
lucasec | 0:350d308e7b77 | 990 | * retrieved using getResponse() as normal. |
lucasec | 0:350d308e7b77 | 991 | */ |
lucasec | 0:350d308e7b77 | 992 | uint8_t waitForStatus(uint8_t frameId, uint16_t timeout); |
lucasec | 0:350d308e7b77 | 993 | private: |
lucasec | 0:350d308e7b77 | 994 | /** |
lucasec | 0:350d308e7b77 | 995 | * Internal version of waitFor that does not need to be |
lucasec | 0:350d308e7b77 | 996 | * templated (to prevent duplication the implementation for |
lucasec | 0:350d308e7b77 | 997 | * every response type you might want to wait for). Instead of |
lucasec | 0:350d308e7b77 | 998 | * using templates, this accepts the apiId to wait for and will |
lucasec | 0:350d308e7b77 | 999 | * cast the given response object and the argument to the given |
lucasec | 0:350d308e7b77 | 1000 | * function to the corresponding type. This means that the |
lucasec | 0:350d308e7b77 | 1001 | * void* given must match the api id! |
lucasec | 0:350d308e7b77 | 1002 | */ |
lucasec | 0:350d308e7b77 | 1003 | uint8_t waitForInternal(uint8_t apiId, void *response, uint16_t timeout, void *func, uintptr_t data, int16_t frameId); |
lucasec | 0:350d308e7b77 | 1004 | |
lucasec | 0:350d308e7b77 | 1005 | /** |
lucasec | 0:350d308e7b77 | 1006 | * Helper that checks if the current response is a status |
lucasec | 0:350d308e7b77 | 1007 | * response with the given frame id. If so, returns the status |
lucasec | 0:350d308e7b77 | 1008 | * byte from the response, otherwise returns 0xff. |
lucasec | 0:350d308e7b77 | 1009 | */ |
lucasec | 0:350d308e7b77 | 1010 | uint8_t matchStatus(uint8_t frameId); |
lucasec | 0:350d308e7b77 | 1011 | |
lucasec | 0:350d308e7b77 | 1012 | /** |
lucasec | 0:350d308e7b77 | 1013 | * Top half of a typical loop(). Calls readPacket(), calls |
lucasec | 0:350d308e7b77 | 1014 | * onPacketError on error, calls onResponse when a response is |
lucasec | 0:350d308e7b77 | 1015 | * available. Returns in the true in the latter case, after |
lucasec | 0:350d308e7b77 | 1016 | * which a caller should typically call loopBottom(). |
lucasec | 0:350d308e7b77 | 1017 | */ |
lucasec | 0:350d308e7b77 | 1018 | bool loopTop(); |
lucasec | 0:350d308e7b77 | 1019 | |
lucasec | 0:350d308e7b77 | 1020 | /** |
lucasec | 0:350d308e7b77 | 1021 | * Bottom half of a typical loop. Call only when a valid |
lucasec | 0:350d308e7b77 | 1022 | * response was read, will call all response-specific callbacks. |
lucasec | 0:350d308e7b77 | 1023 | */ |
lucasec | 0:350d308e7b77 | 1024 | void loopBottom(); |
lucasec | 0:350d308e7b77 | 1025 | |
lucasec | 0:350d308e7b77 | 1026 | template <typename Arg> struct Callback { |
lucasec | 0:350d308e7b77 | 1027 | void (*func)(Arg, uintptr_t); |
lucasec | 0:350d308e7b77 | 1028 | uintptr_t data; |
lucasec | 0:350d308e7b77 | 1029 | void set(void (*func)(Arg, uintptr_t), uintptr_t data) { |
lucasec | 0:350d308e7b77 | 1030 | this->func = func; |
lucasec | 0:350d308e7b77 | 1031 | this->data = data; |
lucasec | 0:350d308e7b77 | 1032 | } |
lucasec | 0:350d308e7b77 | 1033 | bool call(Arg arg) { |
lucasec | 0:350d308e7b77 | 1034 | if (this->func) { |
lucasec | 0:350d308e7b77 | 1035 | this->func(arg, this->data); |
lucasec | 0:350d308e7b77 | 1036 | return true; |
lucasec | 0:350d308e7b77 | 1037 | } |
lucasec | 0:350d308e7b77 | 1038 | return false; |
lucasec | 0:350d308e7b77 | 1039 | } |
lucasec | 0:350d308e7b77 | 1040 | }; |
lucasec | 0:350d308e7b77 | 1041 | |
lucasec | 0:350d308e7b77 | 1042 | Callback<uint8_t> _onPacketError; |
lucasec | 0:350d308e7b77 | 1043 | Callback<XBeeResponse&> _onResponse; |
lucasec | 0:350d308e7b77 | 1044 | Callback<XBeeResponse&> _onOtherResponse; |
lucasec | 0:350d308e7b77 | 1045 | Callback<ZBTxStatusResponse&> _onZBTxStatusResponse; |
lucasec | 0:350d308e7b77 | 1046 | Callback<ZBRxResponse&> _onZBRxResponse; |
lucasec | 0:350d308e7b77 | 1047 | Callback<ZBExplicitRxResponse&> _onZBExplicitRxResponse; |
lucasec | 0:350d308e7b77 | 1048 | Callback<ZBRxIoSampleResponse&> _onZBRxIoSampleResponse; |
lucasec | 0:350d308e7b77 | 1049 | Callback<TxStatusResponse&> _onTxStatusResponse; |
lucasec | 0:350d308e7b77 | 1050 | Callback<Rx16Response&> _onRx16Response; |
lucasec | 0:350d308e7b77 | 1051 | Callback<Rx64Response&> _onRx64Response; |
lucasec | 0:350d308e7b77 | 1052 | Callback<Rx16IoSampleResponse&> _onRx16IoSampleResponse; |
lucasec | 0:350d308e7b77 | 1053 | Callback<Rx64IoSampleResponse&> _onRx64IoSampleResponse; |
lucasec | 0:350d308e7b77 | 1054 | Callback<ModemStatusResponse&> _onModemStatusResponse; |
lucasec | 0:350d308e7b77 | 1055 | Callback<AtCommandResponse&> _onAtCommandResponse; |
lucasec | 0:350d308e7b77 | 1056 | Callback<RemoteAtCommandResponse&> _onRemoteAtCommandResponse; |
lucasec | 0:350d308e7b77 | 1057 | }; |
lucasec | 0:350d308e7b77 | 1058 | |
lucasec | 0:350d308e7b77 | 1059 | /** |
lucasec | 0:350d308e7b77 | 1060 | * All TX packets that support payloads extend this class |
lucasec | 0:350d308e7b77 | 1061 | */ |
lucasec | 0:350d308e7b77 | 1062 | class PayloadRequest : public XBeeRequest { |
lucasec | 0:350d308e7b77 | 1063 | public: |
lucasec | 0:350d308e7b77 | 1064 | PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint8_t payloadLength); |
lucasec | 0:350d308e7b77 | 1065 | /** |
lucasec | 0:350d308e7b77 | 1066 | * Returns the payload of the packet, if not null |
lucasec | 0:350d308e7b77 | 1067 | */ |
lucasec | 0:350d308e7b77 | 1068 | uint8_t* getPayload(); |
lucasec | 0:350d308e7b77 | 1069 | /** |
lucasec | 0:350d308e7b77 | 1070 | * Sets the payload array |
lucasec | 0:350d308e7b77 | 1071 | */ |
lucasec | 0:350d308e7b77 | 1072 | void setPayload(uint8_t* payloadPtr); |
lucasec | 0:350d308e7b77 | 1073 | |
lucasec | 0:350d308e7b77 | 1074 | /* |
lucasec | 0:350d308e7b77 | 1075 | * Set the payload and its length in one call. |
lucasec | 0:350d308e7b77 | 1076 | */ |
lucasec | 0:350d308e7b77 | 1077 | void setPayload(uint8_t* payloadPtr, uint8_t payloadLength) { |
lucasec | 0:350d308e7b77 | 1078 | setPayload(payloadPtr); |
lucasec | 0:350d308e7b77 | 1079 | setPayloadLength(payloadLength); |
lucasec | 0:350d308e7b77 | 1080 | } |
lucasec | 0:350d308e7b77 | 1081 | |
lucasec | 0:350d308e7b77 | 1082 | /** |
lucasec | 0:350d308e7b77 | 1083 | * Returns the length of the payload array, as specified by the user. |
lucasec | 0:350d308e7b77 | 1084 | */ |
lucasec | 0:350d308e7b77 | 1085 | uint8_t getPayloadLength(); |
lucasec | 0:350d308e7b77 | 1086 | /** |
lucasec | 0:350d308e7b77 | 1087 | * Sets the length of the payload to include in the request. For example if the payload array |
lucasec | 0:350d308e7b77 | 1088 | * is 50 bytes and you only want the first 10 to be included in the packet, set the length to 10. |
lucasec | 0:350d308e7b77 | 1089 | * Length must be <= to the array length. |
lucasec | 0:350d308e7b77 | 1090 | */ |
lucasec | 0:350d308e7b77 | 1091 | void setPayloadLength(uint8_t payloadLength); |
lucasec | 0:350d308e7b77 | 1092 | private: |
lucasec | 0:350d308e7b77 | 1093 | uint8_t* _payloadPtr; |
lucasec | 0:350d308e7b77 | 1094 | uint8_t _payloadLength; |
lucasec | 0:350d308e7b77 | 1095 | }; |
lucasec | 0:350d308e7b77 | 1096 | |
lucasec | 0:350d308e7b77 | 1097 | #ifdef SERIES_1 |
lucasec | 0:350d308e7b77 | 1098 | |
lucasec | 0:350d308e7b77 | 1099 | /** |
lucasec | 0:350d308e7b77 | 1100 | * Represents a Series 1 TX packet that corresponds to Api Id: TX_16_REQUEST |
lucasec | 0:350d308e7b77 | 1101 | * <p/> |
lucasec | 0:350d308e7b77 | 1102 | * Be careful not to send a data array larger than the max packet size of your radio. |
lucasec | 0:350d308e7b77 | 1103 | * This class does not perform any validation of packet size and there will be no indication |
lucasec | 0:350d308e7b77 | 1104 | * if the packet is too large, other than you will not get a TX Status response. |
lucasec | 0:350d308e7b77 | 1105 | * The datasheet says 100 bytes is the maximum, although that could change in future firmware. |
lucasec | 0:350d308e7b77 | 1106 | */ |
lucasec | 0:350d308e7b77 | 1107 | class Tx16Request : public PayloadRequest { |
lucasec | 0:350d308e7b77 | 1108 | public: |
lucasec | 0:350d308e7b77 | 1109 | Tx16Request(uint16_t addr16, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); |
lucasec | 0:350d308e7b77 | 1110 | /** |
lucasec | 0:350d308e7b77 | 1111 | * Creates a Unicast Tx16Request with the ACK option and DEFAULT_FRAME_ID |
lucasec | 0:350d308e7b77 | 1112 | */ |
lucasec | 0:350d308e7b77 | 1113 | Tx16Request(uint16_t addr16, uint8_t *payload, uint8_t payloadLength); |
lucasec | 0:350d308e7b77 | 1114 | /** |
lucasec | 0:350d308e7b77 | 1115 | * Creates a default instance of this class. At a minimum you must specify |
lucasec | 0:350d308e7b77 | 1116 | * a payload, payload length and a destination address before sending this request. |
lucasec | 0:350d308e7b77 | 1117 | */ |
lucasec | 0:350d308e7b77 | 1118 | Tx16Request(); |
lucasec | 0:350d308e7b77 | 1119 | uint16_t getAddress16(); |
lucasec | 0:350d308e7b77 | 1120 | void setAddress16(uint16_t addr16); |
lucasec | 0:350d308e7b77 | 1121 | uint8_t getOption(); |
lucasec | 0:350d308e7b77 | 1122 | void setOption(uint8_t option); |
lucasec | 0:350d308e7b77 | 1123 | virtual uint8_t getFrameData(uint8_t pos); |
lucasec | 0:350d308e7b77 | 1124 | virtual uint8_t getFrameDataLength(); |
lucasec | 0:350d308e7b77 | 1125 | protected: |
lucasec | 0:350d308e7b77 | 1126 | private: |
lucasec | 0:350d308e7b77 | 1127 | uint16_t _addr16; |
lucasec | 0:350d308e7b77 | 1128 | uint8_t _option; |
lucasec | 0:350d308e7b77 | 1129 | }; |
lucasec | 0:350d308e7b77 | 1130 | |
lucasec | 0:350d308e7b77 | 1131 | /** |
lucasec | 0:350d308e7b77 | 1132 | * Represents a Series 1 TX packet that corresponds to Api Id: TX_64_REQUEST |
lucasec | 0:350d308e7b77 | 1133 | * |
lucasec | 0:350d308e7b77 | 1134 | * Be careful not to send a data array larger than the max packet size of your radio. |
lucasec | 0:350d308e7b77 | 1135 | * This class does not perform any validation of packet size and there will be no indication |
lucasec | 0:350d308e7b77 | 1136 | * if the packet is too large, other than you will not get a TX Status response. |
lucasec | 0:350d308e7b77 | 1137 | * The datasheet says 100 bytes is the maximum, although that could change in future firmware. |
lucasec | 0:350d308e7b77 | 1138 | */ |
lucasec | 0:350d308e7b77 | 1139 | class Tx64Request : public PayloadRequest { |
lucasec | 0:350d308e7b77 | 1140 | public: |
lucasec | 0:350d308e7b77 | 1141 | Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); |
lucasec | 0:350d308e7b77 | 1142 | /** |
lucasec | 0:350d308e7b77 | 1143 | * Creates a unicast Tx64Request with the ACK option and DEFAULT_FRAME_ID |
lucasec | 0:350d308e7b77 | 1144 | */ |
lucasec | 0:350d308e7b77 | 1145 | Tx64Request(XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength); |
lucasec | 0:350d308e7b77 | 1146 | /** |
lucasec | 0:350d308e7b77 | 1147 | * Creates a default instance of this class. At a minimum you must specify |
lucasec | 0:350d308e7b77 | 1148 | * a payload, payload length and a destination address before sending this request. |
lucasec | 0:350d308e7b77 | 1149 | */ |
lucasec | 0:350d308e7b77 | 1150 | Tx64Request(); |
lucasec | 0:350d308e7b77 | 1151 | XBeeAddress64& getAddress64(); |
lucasec | 0:350d308e7b77 | 1152 | void setAddress64(XBeeAddress64& addr64); |
lucasec | 0:350d308e7b77 | 1153 | // TODO move option to superclass |
lucasec | 0:350d308e7b77 | 1154 | uint8_t getOption(); |
lucasec | 0:350d308e7b77 | 1155 | void setOption(uint8_t option); |
lucasec | 0:350d308e7b77 | 1156 | virtual uint8_t getFrameData(uint8_t pos); |
lucasec | 0:350d308e7b77 | 1157 | virtual uint8_t getFrameDataLength(); |
lucasec | 0:350d308e7b77 | 1158 | private: |
lucasec | 0:350d308e7b77 | 1159 | XBeeAddress64 _addr64; |
lucasec | 0:350d308e7b77 | 1160 | uint8_t _option; |
lucasec | 0:350d308e7b77 | 1161 | }; |
lucasec | 0:350d308e7b77 | 1162 | |
lucasec | 0:350d308e7b77 | 1163 | #endif |
lucasec | 0:350d308e7b77 | 1164 | |
lucasec | 0:350d308e7b77 | 1165 | |
lucasec | 0:350d308e7b77 | 1166 | #ifdef SERIES_2 |
lucasec | 0:350d308e7b77 | 1167 | |
lucasec | 0:350d308e7b77 | 1168 | /** |
lucasec | 0:350d308e7b77 | 1169 | * Represents a Series 2 TX packet that corresponds to Api Id: ZB_TX_REQUEST |
lucasec | 0:350d308e7b77 | 1170 | * |
lucasec | 0:350d308e7b77 | 1171 | * Be careful not to send a data array larger than the max packet size of your radio. |
lucasec | 0:350d308e7b77 | 1172 | * This class does not perform any validation of packet size and there will be no indication |
lucasec | 0:350d308e7b77 | 1173 | * if the packet is too large, other than you will not get a TX Status response. |
lucasec | 0:350d308e7b77 | 1174 | * The datasheet says 72 bytes is the maximum for ZNet firmware and ZB Pro firmware provides |
lucasec | 0:350d308e7b77 | 1175 | * the ATNP command to get the max supported payload size. This command is useful since the |
lucasec | 0:350d308e7b77 | 1176 | * maximum payload size varies according to certain settings, such as encryption. |
lucasec | 0:350d308e7b77 | 1177 | * ZB Pro firmware provides a PAYLOAD_TOO_LARGE that is returned if payload size |
lucasec | 0:350d308e7b77 | 1178 | * exceeds the maximum. |
lucasec | 0:350d308e7b77 | 1179 | */ |
lucasec | 0:350d308e7b77 | 1180 | class ZBTxRequest : public PayloadRequest { |
lucasec | 0:350d308e7b77 | 1181 | public: |
lucasec | 0:350d308e7b77 | 1182 | /** |
lucasec | 0:350d308e7b77 | 1183 | * Creates a unicast ZBTxRequest with the ACK option and DEFAULT_FRAME_ID |
lucasec | 0:350d308e7b77 | 1184 | */ |
lucasec | 0:350d308e7b77 | 1185 | ZBTxRequest(const XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength); |
lucasec | 0:350d308e7b77 | 1186 | ZBTxRequest(const XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); |
lucasec | 0:350d308e7b77 | 1187 | /** |
lucasec | 0:350d308e7b77 | 1188 | * Creates a default instance of this class. At a minimum you must specify |
lucasec | 0:350d308e7b77 | 1189 | * a payload, payload length and a 64-bit destination address before sending |
lucasec | 0:350d308e7b77 | 1190 | * this request. |
lucasec | 0:350d308e7b77 | 1191 | */ |
lucasec | 0:350d308e7b77 | 1192 | ZBTxRequest(); |
lucasec | 0:350d308e7b77 | 1193 | XBeeAddress64& getAddress64(); |
lucasec | 0:350d308e7b77 | 1194 | uint16_t getAddress16(); |
lucasec | 0:350d308e7b77 | 1195 | uint8_t getBroadcastRadius(); |
lucasec | 0:350d308e7b77 | 1196 | uint8_t getOption(); |
lucasec | 0:350d308e7b77 | 1197 | void setAddress64(const XBeeAddress64& addr64); |
lucasec | 0:350d308e7b77 | 1198 | void setAddress16(uint16_t addr16); |
lucasec | 0:350d308e7b77 | 1199 | void setBroadcastRadius(uint8_t broadcastRadius); |
lucasec | 0:350d308e7b77 | 1200 | void setOption(uint8_t option); |
lucasec | 0:350d308e7b77 | 1201 | protected: |
lucasec | 0:350d308e7b77 | 1202 | // declare virtual functions |
lucasec | 0:350d308e7b77 | 1203 | virtual uint8_t getFrameData(uint8_t pos); |
lucasec | 0:350d308e7b77 | 1204 | virtual uint8_t getFrameDataLength(); |
lucasec | 0:350d308e7b77 | 1205 | XBeeAddress64 _addr64; |
lucasec | 0:350d308e7b77 | 1206 | uint16_t _addr16; |
lucasec | 0:350d308e7b77 | 1207 | uint8_t _broadcastRadius; |
lucasec | 0:350d308e7b77 | 1208 | uint8_t _option; |
lucasec | 0:350d308e7b77 | 1209 | }; |
lucasec | 0:350d308e7b77 | 1210 | |
lucasec | 0:350d308e7b77 | 1211 | /** |
lucasec | 0:350d308e7b77 | 1212 | * Represents a Series 2 TX packet that corresponds to Api Id: ZB_EXPLICIT_TX_REQUEST |
lucasec | 0:350d308e7b77 | 1213 | * |
lucasec | 0:350d308e7b77 | 1214 | * See the warning about maximum packet size for ZBTxRequest above, |
lucasec | 0:350d308e7b77 | 1215 | * which probably also applies here as well. |
lucasec | 0:350d308e7b77 | 1216 | * |
lucasec | 0:350d308e7b77 | 1217 | * Note that to distinguish reply packets from non-XBee devices, set |
lucasec | 0:350d308e7b77 | 1218 | * AO=1 to enable reception of ZBExplicitRxResponse packets. |
lucasec | 0:350d308e7b77 | 1219 | */ |
lucasec | 0:350d308e7b77 | 1220 | class ZBExplicitTxRequest : public ZBTxRequest { |
lucasec | 0:350d308e7b77 | 1221 | public: |
lucasec | 0:350d308e7b77 | 1222 | /** |
lucasec | 0:350d308e7b77 | 1223 | * Creates a unicast ZBExplicitTxRequest with the ACK option and |
lucasec | 0:350d308e7b77 | 1224 | * DEFAULT_FRAME_ID. |
lucasec | 0:350d308e7b77 | 1225 | * |
lucasec | 0:350d308e7b77 | 1226 | * It uses the Maxstream profile (0xc105), both endpoints 232 |
lucasec | 0:350d308e7b77 | 1227 | * and cluster 0x0011, resulting in the same packet as sent by a |
lucasec | 0:350d308e7b77 | 1228 | * normal ZBTxRequest. |
lucasec | 0:350d308e7b77 | 1229 | */ |
lucasec | 0:350d308e7b77 | 1230 | ZBExplicitTxRequest(XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength); |
lucasec | 0:350d308e7b77 | 1231 | /** |
lucasec | 0:350d308e7b77 | 1232 | * Create a ZBExplicitTxRequest, specifying all fields. |
lucasec | 0:350d308e7b77 | 1233 | */ |
lucasec | 0:350d308e7b77 | 1234 | ZBExplicitTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId, uint8_t srcEndpoint, uint8_t dstEndpoint, uint16_t clusterId, uint16_t profileId); |
lucasec | 0:350d308e7b77 | 1235 | /** |
lucasec | 0:350d308e7b77 | 1236 | * Creates a default instance of this class. At a minimum you |
lucasec | 0:350d308e7b77 | 1237 | * must specify a payload, payload length and a destination |
lucasec | 0:350d308e7b77 | 1238 | * address before sending this request. |
lucasec | 0:350d308e7b77 | 1239 | * |
lucasec | 0:350d308e7b77 | 1240 | * Furthermore, it uses the Maxstream profile (0xc105), both |
lucasec | 0:350d308e7b77 | 1241 | * endpoints 232 and cluster 0x0011, resulting in the same |
lucasec | 0:350d308e7b77 | 1242 | * packet as sent by a normal ZBExplicitTxRequest. |
lucasec | 0:350d308e7b77 | 1243 | */ |
lucasec | 0:350d308e7b77 | 1244 | ZBExplicitTxRequest(); |
lucasec | 0:350d308e7b77 | 1245 | uint8_t getSrcEndpoint(); |
lucasec | 0:350d308e7b77 | 1246 | uint8_t getDstEndpoint(); |
lucasec | 0:350d308e7b77 | 1247 | uint16_t getClusterId(); |
lucasec | 0:350d308e7b77 | 1248 | uint16_t getProfileId(); |
lucasec | 0:350d308e7b77 | 1249 | void setSrcEndpoint(uint8_t endpoint); |
lucasec | 0:350d308e7b77 | 1250 | void setDstEndpoint(uint8_t endpoint); |
lucasec | 0:350d308e7b77 | 1251 | void setClusterId(uint16_t clusterId); |
lucasec | 0:350d308e7b77 | 1252 | void setProfileId(uint16_t profileId); |
lucasec | 0:350d308e7b77 | 1253 | protected: |
lucasec | 0:350d308e7b77 | 1254 | // declare virtual functions |
lucasec | 0:350d308e7b77 | 1255 | virtual uint8_t getFrameData(uint8_t pos); |
lucasec | 0:350d308e7b77 | 1256 | virtual uint8_t getFrameDataLength(); |
lucasec | 0:350d308e7b77 | 1257 | private: |
lucasec | 0:350d308e7b77 | 1258 | uint8_t _srcEndpoint; |
lucasec | 0:350d308e7b77 | 1259 | uint8_t _dstEndpoint; |
lucasec | 0:350d308e7b77 | 1260 | uint16_t _profileId; |
lucasec | 0:350d308e7b77 | 1261 | uint16_t _clusterId; |
lucasec | 0:350d308e7b77 | 1262 | }; |
lucasec | 0:350d308e7b77 | 1263 | |
lucasec | 0:350d308e7b77 | 1264 | #endif |
lucasec | 0:350d308e7b77 | 1265 | |
lucasec | 0:350d308e7b77 | 1266 | /** |
lucasec | 0:350d308e7b77 | 1267 | * Represents an AT Command TX packet |
lucasec | 0:350d308e7b77 | 1268 | * The command is used to configure the serially connected XBee radio |
lucasec | 0:350d308e7b77 | 1269 | */ |
lucasec | 0:350d308e7b77 | 1270 | class AtCommandRequest : public XBeeRequest { |
lucasec | 0:350d308e7b77 | 1271 | public: |
lucasec | 0:350d308e7b77 | 1272 | AtCommandRequest(); |
lucasec | 0:350d308e7b77 | 1273 | AtCommandRequest(uint8_t *command); |
lucasec | 0:350d308e7b77 | 1274 | AtCommandRequest(uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength); |
lucasec | 0:350d308e7b77 | 1275 | virtual uint8_t getFrameData(uint8_t pos); |
lucasec | 0:350d308e7b77 | 1276 | virtual uint8_t getFrameDataLength(); |
lucasec | 0:350d308e7b77 | 1277 | uint8_t* getCommand(); |
lucasec | 0:350d308e7b77 | 1278 | void setCommand(uint8_t* command); |
lucasec | 0:350d308e7b77 | 1279 | uint8_t* getCommandValue(); |
lucasec | 0:350d308e7b77 | 1280 | void setCommandValue(uint8_t* command); |
lucasec | 0:350d308e7b77 | 1281 | uint8_t getCommandValueLength(); |
lucasec | 0:350d308e7b77 | 1282 | void setCommandValueLength(uint8_t length); |
lucasec | 0:350d308e7b77 | 1283 | /** |
lucasec | 0:350d308e7b77 | 1284 | * Clears the optional commandValue and commandValueLength so that a query may be sent |
lucasec | 0:350d308e7b77 | 1285 | */ |
lucasec | 0:350d308e7b77 | 1286 | void clearCommandValue(); |
lucasec | 0:350d308e7b77 | 1287 | //void reset(); |
lucasec | 0:350d308e7b77 | 1288 | private: |
lucasec | 0:350d308e7b77 | 1289 | uint8_t *_command; |
lucasec | 0:350d308e7b77 | 1290 | uint8_t *_commandValue; |
lucasec | 0:350d308e7b77 | 1291 | uint8_t _commandValueLength; |
lucasec | 0:350d308e7b77 | 1292 | }; |
lucasec | 0:350d308e7b77 | 1293 | |
lucasec | 0:350d308e7b77 | 1294 | /** |
lucasec | 0:350d308e7b77 | 1295 | * Represents an Remote AT Command TX packet |
lucasec | 0:350d308e7b77 | 1296 | * The command is used to configure a remote XBee radio |
lucasec | 0:350d308e7b77 | 1297 | */ |
lucasec | 0:350d308e7b77 | 1298 | class RemoteAtCommandRequest : public AtCommandRequest { |
lucasec | 0:350d308e7b77 | 1299 | public: |
lucasec | 0:350d308e7b77 | 1300 | RemoteAtCommandRequest(); |
lucasec | 0:350d308e7b77 | 1301 | /** |
lucasec | 0:350d308e7b77 | 1302 | * Creates a RemoteAtCommandRequest with 16-bit address to set a command. |
lucasec | 0:350d308e7b77 | 1303 | * 64-bit address defaults to broadcast and applyChanges is true. |
lucasec | 0:350d308e7b77 | 1304 | */ |
lucasec | 0:350d308e7b77 | 1305 | RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength); |
lucasec | 0:350d308e7b77 | 1306 | /** |
lucasec | 0:350d308e7b77 | 1307 | * Creates a RemoteAtCommandRequest with 16-bit address to query a command. |
lucasec | 0:350d308e7b77 | 1308 | * 64-bit address defaults to broadcast and applyChanges is true. |
lucasec | 0:350d308e7b77 | 1309 | */ |
lucasec | 0:350d308e7b77 | 1310 | RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command); |
lucasec | 0:350d308e7b77 | 1311 | /** |
lucasec | 0:350d308e7b77 | 1312 | * Creates a RemoteAtCommandRequest with 64-bit address to set a command. |
lucasec | 0:350d308e7b77 | 1313 | * 16-bit address defaults to broadcast and applyChanges is true. |
lucasec | 0:350d308e7b77 | 1314 | */ |
lucasec | 0:350d308e7b77 | 1315 | RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength); |
lucasec | 0:350d308e7b77 | 1316 | /** |
lucasec | 0:350d308e7b77 | 1317 | * Creates a RemoteAtCommandRequest with 16-bit address to query a command. |
lucasec | 0:350d308e7b77 | 1318 | * 16-bit address defaults to broadcast and applyChanges is true. |
lucasec | 0:350d308e7b77 | 1319 | */ |
lucasec | 0:350d308e7b77 | 1320 | RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command); |
lucasec | 0:350d308e7b77 | 1321 | uint16_t getRemoteAddress16(); |
lucasec | 0:350d308e7b77 | 1322 | void setRemoteAddress16(uint16_t remoteAddress16); |
lucasec | 0:350d308e7b77 | 1323 | XBeeAddress64& getRemoteAddress64(); |
lucasec | 0:350d308e7b77 | 1324 | void setRemoteAddress64(XBeeAddress64 &remoteAddress64); |
lucasec | 0:350d308e7b77 | 1325 | bool getApplyChanges(); |
lucasec | 0:350d308e7b77 | 1326 | void setApplyChanges(bool applyChanges); |
lucasec | 0:350d308e7b77 | 1327 | virtual uint8_t getFrameData(uint8_t pos); |
lucasec | 0:350d308e7b77 | 1328 | virtual uint8_t getFrameDataLength(); |
lucasec | 0:350d308e7b77 | 1329 | static XBeeAddress64 broadcastAddress64; |
lucasec | 0:350d308e7b77 | 1330 | // static uint16_t broadcast16Address; |
lucasec | 0:350d308e7b77 | 1331 | private: |
lucasec | 0:350d308e7b77 | 1332 | XBeeAddress64 _remoteAddress64; |
lucasec | 0:350d308e7b77 | 1333 | uint16_t _remoteAddress16; |
lucasec | 0:350d308e7b77 | 1334 | bool _applyChanges; |
lucasec | 0:350d308e7b77 | 1335 | }; |
lucasec | 0:350d308e7b77 | 1336 | |
lucasec | 0:350d308e7b77 | 1337 | |
lucasec | 0:350d308e7b77 | 1338 | |
lucasec | 0:350d308e7b77 | 1339 | #endif //XBee_h |
lucasec | 0:350d308e7b77 | 1340 |