XBee-mbed library http://mbed.org/users/okini3939/notebook/xbee-mbed/

Dependents:   device_server_udp led_sender_post XBee_API_ex1 XBee_API_ex2 ... more

Files at this revision

API Documentation at this revision

Comitter:
okini3939
Date:
Tue Mar 13 09:01:52 2012 +0000
Parent:
3:8573b122fa84
Child:
5:547cfff7adf7
Commit message:

Changed in this revision

XBee.cpp Show annotated file Show diff for this revision Revisions of this file
XBee.h Show annotated file Show diff for this revision Revisions of this file
XBeeWiFi.cpp Show annotated file Show diff for this revision Revisions of this file
XBeeWiFi.h Show annotated file Show diff for this revision Revisions of this file
--- a/XBee.cpp	Thu Mar 08 17:41:29 2012 +0000
+++ b/XBee.cpp	Tue Mar 13 09:01:52 2012 +0000
@@ -67,11 +67,11 @@
     _checksum = checksum;
 }
 
-uint8_t XBeeResponse::getFrameDataLength() {
+uint16_t XBeeResponse::getFrameDataLength() {
     return _frameLength;
 }
 
-void XBeeResponse::setFrameLength(uint8_t frameLength) {
+void XBeeResponse::setFrameLength(uint16_t frameLength) {
     _frameLength = frameLength;
 }
 
@@ -158,7 +158,7 @@
     return 11;
 }
 
-uint8_t ZBRxResponse::getDataLength() {
+uint16_t ZBRxResponse::getDataLength() {
     return getPacketLength() - getDataOffset() - 1;
 }
 
@@ -461,7 +461,7 @@
     return (getOption() & 4) == 4;
 }
 
-uint8_t RxResponse::getDataLength() {
+uint16_t RxResponse::getDataLength() {
     return getPacketLength() - getDataOffset() - 1;
 }
 
@@ -519,7 +519,7 @@
     return getStatus() == AT_OK;
 }
 
-uint8_t RemoteAtCommandResponse::getValueLength() {
+uint16_t RemoteAtCommandResponse::getValueLength() {
     return getFrameDataLength() - 14;
 }
 
@@ -605,7 +605,7 @@
     return getFrameData()[3];
 }
 
-uint8_t AtCommandResponse::getValueLength() {
+uint16_t AtCommandResponse::getValueLength() {
     return getFrameDataLength() - 4;
 }
 
@@ -632,7 +632,7 @@
 }
 
 uint16_t XBeeResponse::getPacketLength() {
-    return ((_msbLength << 8) & 0xff) + (_lsbLength & 0xff);
+    return ((uint16_t)_msbLength << 8) + _lsbLength;
 }
 
 uint8_t* XBeeResponse::getFrameData() {
@@ -664,27 +664,60 @@
 
 void XBee::resetResponse() {
     _pos = 0;
+    _epos = 0;
     _escape = false;
+    _checksumTotal = 0;
     _response.reset();
 }
 
 XBee::XBee(PinName p_tx, PinName p_rx): _xbee(p_tx, p_rx) {
     _pos = 0;
+    _epos = 0;
     _escape = false;
     _checksumTotal = 0;
     _nextFrameId = 0;
-    _cts = NULL;
 
     _response.init();
     _response.setFrameData(_responseFrameData);
 }
 
-XBee::XBee(PinName p_tx, PinName p_rx, PinName p_cts): _xbee(p_tx, p_rx) {
+XBee::XBee(PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts): _xbee(p_tx, p_rx) {
     _pos = 0;
+    _epos = 0;
     _escape = false;
     _checksumTotal = 0;
     _nextFrameId = 0;
-    _cts = new DigitalIn(p_cts);
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+    if (p_cts == p12) { // CTS (P0_17)
+        LPC_UART1->MCR |= (1<<7); // CTSEN
+        LPC_PINCON->PINSEL1 &= ~(3 << 2);
+        LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
+    }
+    if (p_rts == P0_22) { // RTS (P0_22)
+        LPC_UART1->MCR |= (1<<6); // RTSEN
+        LPC_PINCON->PINSEL1 &= ~(3 << 12);
+        LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
+        _xbee.attach(this, &XBee::isr_recv, Serial::RxIrq);
+        _rts = true;
+    } else {
+        _rts = false;
+    }
+#elif defined(TARGET_LPC11U24)
+    if (p_cts == p21) { // CTS (P0_7)
+        LPC_UART->MCR = (1<<7); // CTSEN
+        LPC_IOCON->PIO0_7 &= ~0x07;
+        LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
+    }
+    if (p_rts == p22) { // RTS (P0_17)
+        LPC_UART->MCR = (1<<6); // RTSEN
+        LPC_IOCON->PIO0_17 &= ~0x07;
+        LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
+        _xbee.attach(this, &XBee::isr_recv, Serial::RxIrq);
+        _rts = true;
+    } else {
+        _rts = false;
+    }
+#endif
 
     _response.init();
     _response.setFrameData(_responseFrameData);
@@ -760,11 +793,30 @@
          }
     }
 
+    DBG("(timeout %d %d)\r\n", _pos, _epos);
     // timed out
     t.stop();
     return false;
 }
 
+void XBee::isr_recv () {
+    _rxbuf[_rxaddr_w] = _xbee.getc();
+    _rxaddr_w = (_rxaddr_w + 1) % MAX_RXBUF_SIZE;
+}
+
+int XBee::getbuf () {
+    int r;
+    __disable_irq();
+    r = _rxbuf[_rxaddr_r];
+    _rxaddr_r = (_rxaddr_r + 1) % MAX_RXBUF_SIZE;
+    __enable_irq();
+    return r;
+}
+
+int XBee::bufreadable () {
+    return _rxaddr_w != _rxaddr_r;
+}
+
 void XBee::readPacket() {
     // reset previous response
     if (_response.isAvailable() || _response.isError()) {
@@ -772,20 +824,33 @@
         resetResponse();
     }
 
-    while (_xbee.readable()) {
+//    while (_xbee.readable()) {
+    while ((! _rts && _xbee.readable()) || (_rts && bufreadable())) {
 
-        b = _xbee.getc();
+//        b = _xbee.getc();
+        if (_rts) {
+            b = getbuf();
+        } else {
+            b = _xbee.getc();
+        }
 
         if (_pos > 0 && b == START_BYTE && ATAP == 2) {
             // new packet start before previous packeted completed -- discard previous packet and start over
+            DBG("error: %02x %d %d\r\n", b, _pos, _epos);
             _response.setErrorCode(UNEXPECTED_START_BYTE);
             return;
         }
 
         if (_pos > 0 && b == ESCAPE) {
             if (_xbee.readable()) {
-                b = _xbee.getc();
+//                b = _xbee.getc();
+                if (_rts) {
+                    b = getbuf();
+                } else {
+                    b = _xbee.getc();
+                }
                 b = 0x20 ^ b;
+                _epos ++;
             } else {
                 // escape byte.  next byte will be
                 _escape = true;
@@ -797,6 +862,7 @@
         if (_escape == true) {
             b = 0x20 ^ b;
             _escape = false;
+            _epos ++;
         }
 
         // checksum includes all bytes starting with api id
@@ -840,10 +906,10 @@
                 // check if we're at the end of the packet
                 // packet length does not include start, length, or checksum bytes, so add 3
                 if (_pos == (_response.getPacketLength() + 3)) {
+//                if (_pos + _epos == (_response.getPacketLength() + 3)) {
                     // verify checksum
 
                     //std::cout << "read checksum " << static_cast<unsigned int>(b) << " at pos " << static_cast<unsigned int>(_pos) << std::endl;
-
                     if ((_checksumTotal & 0xff) == 0xff) {
                         _response.setChecksum(b);
                         _response.setAvailable(true);
@@ -851,6 +917,7 @@
                         _response.setErrorCode(NO_ERROR);
                     } else {
                         // checksum failed
+                        DBG("error: checksum %02x %02x %d %d\r\n", b, _checksumTotal, _pos, _epos);
                         _response.setErrorCode(CHECKSUM_FAILURE);
                     }
 
@@ -860,6 +927,7 @@
 
                     // reset state vars
                     _pos = 0;
+                    _epos = 0;
 
                     _checksumTotal = 0;
 
@@ -909,7 +977,7 @@
 //}
 
 
-PayloadRequest::PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint8_t payloadLength) : XBeeRequest(apiId, frameId) {
+PayloadRequest::PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint16_t payloadLength) : XBeeRequest(apiId, frameId) {
     _payloadPtr = payload;
     _payloadLength = payloadLength;
 }
@@ -922,11 +990,11 @@
     _payloadPtr = payload;
 }
 
-uint8_t PayloadRequest::getPayloadLength() {
+uint16_t PayloadRequest::getPayloadLength() {
     return _payloadLength;
 }
 
-void PayloadRequest::setPayloadLength(uint8_t payloadLength) {
+void PayloadRequest::setPayloadLength(uint16_t payloadLength) {
     _payloadLength = payloadLength;
 }
 
@@ -967,21 +1035,21 @@
 
 }
 
-ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId): PayloadRequest(ZB_TX_REQUEST, frameId, data, dataLength) {
+ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId): PayloadRequest(ZB_TX_REQUEST, frameId, data, dataLength) {
     _addr64 = addr64;
     _addr16 = addr16;
     _broadcastRadius = broadcastRadius;
     _option = option;
 }
 
-ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint8_t *data, uint8_t dataLength): PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
+ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint8_t *data, uint16_t dataLength): PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
     _addr64 = addr64;
     _addr16 = ZB_BROADCAST_ADDRESS;
     _broadcastRadius = ZB_BROADCAST_RADIUS_MAX_HOPS;
     _option = ZB_TX_UNICAST;
 }
 
-uint8_t ZBTxRequest::getFrameData(uint8_t pos) {
+uint8_t ZBTxRequest::getFrameData(uint16_t pos) {
     if (pos == 0) {
         return (_addr64.getMsb() >> 24) & 0xff;
     } else if (pos == 1) {
@@ -1011,7 +1079,7 @@
     }
 }
 
-uint8_t ZBTxRequest::getFrameDataLength() {
+uint16_t ZBTxRequest::getFrameDataLength() {
     return ZB_TX_API_LENGTH + getPayloadLength();
 }
 
@@ -1055,17 +1123,17 @@
 
 }
 
-Tx16Request::Tx16Request(uint16_t addr16, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId) : PayloadRequest(TX_16_REQUEST, frameId, data, dataLength) {
+Tx16Request::Tx16Request(uint16_t addr16, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId) : PayloadRequest(TX_16_REQUEST, frameId, data, dataLength) {
     _addr16 = addr16;
     _option = option;
 }
 
-Tx16Request::Tx16Request(uint16_t addr16, uint8_t *data, uint8_t dataLength) : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
+Tx16Request::Tx16Request(uint16_t addr16, uint8_t *data, uint16_t dataLength) : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
     _addr16 = addr16;
     _option = ACK_OPTION;
 }
 
-uint8_t Tx16Request::getFrameData(uint8_t pos) {
+uint8_t Tx16Request::getFrameData(uint16_t pos) {
 
     if (pos == 0) {
         return (_addr16 >> 8) & 0xff;
@@ -1078,7 +1146,7 @@
     }
 }
 
-uint8_t Tx16Request::getFrameDataLength() {
+uint16_t Tx16Request::getFrameDataLength() {
     return TX_16_API_LENGTH + getPayloadLength();
 }
 
@@ -1102,17 +1170,17 @@
 
 }
 
-Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId) : PayloadRequest(TX_64_REQUEST, frameId, data, dataLength) {
+Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId) : PayloadRequest(TX_64_REQUEST, frameId, data, dataLength) {
     _addr64 = addr64;
     _option = option;
 }
 
-Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t *data, uint8_t dataLength) : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
+Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t *data, uint16_t dataLength) : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
     _addr64 = addr64;
     _option = ACK_OPTION;
 }
 
-uint8_t Tx64Request::getFrameData(uint8_t pos) {
+uint8_t Tx64Request::getFrameData(uint16_t pos) {
 
     if (pos == 0) {
         return (_addr64.getMsb() >> 24) & 0xff;
@@ -1137,7 +1205,7 @@
     }
 }
 
-uint8_t Tx64Request::getFrameDataLength() {
+uint16_t Tx64Request::getFrameDataLength() {
     return TX_64_API_LENGTH + getPayloadLength();
 }
 
@@ -1199,7 +1267,7 @@
     _commandValueLength = length;
 }
 
-uint8_t AtCommandRequest::getFrameData(uint8_t pos) {
+uint8_t AtCommandRequest::getFrameData(uint16_t pos) {
 
     if (pos == 0) {
         return _command[0];
@@ -1219,7 +1287,7 @@
 //     XBeeRequest::reset();
 //}
 
-uint8_t AtCommandRequest::getFrameDataLength() {
+uint16_t AtCommandRequest::getFrameDataLength() {
     // command is 2 byte + length of value
     return AT_COMMAND_API_LENGTH + _commandValueLength;
 }
@@ -1286,7 +1354,7 @@
 }
 
 
-uint8_t RemoteAtCommandRequest::getFrameData(uint8_t pos) {
+uint8_t RemoteAtCommandRequest::getFrameData(uint16_t pos) {
     if (pos == 0) {
         return (_remoteAddress64.getMsb() >> 24) & 0xff;
     } else if (pos == 1) {
@@ -1318,7 +1386,7 @@
     }
 }
 
-uint8_t RemoteAtCommandRequest::getFrameDataLength() {
+uint16_t RemoteAtCommandRequest::getFrameDataLength() {
     return REMOTE_AT_COMMAND_API_LENGTH + getCommandValueLength();
 }
 
@@ -1376,12 +1444,9 @@
 
     if (escape && (b == START_BYTE || b == ESCAPE || b == XON || b == XOFF)) {
 //        std::cout << "escaping byte [" << toHexString(b) << "] " << std::endl;
-        if (_cts) while (_cts->read() != 0);
         _xbee.putc(ESCAPE);
-        if (_cts) while (_cts->read() != 0);
         _xbee.putc(b ^ 0x20);
     } else {
-        if (_cts) while (_cts->read() != 0);
         _xbee.putc(b);
     }
     DBG("%02x ", b);
--- a/XBee.h	Thu Mar 08 17:41:29 2012 +0000
+++ b/XBee.h	Tue Mar 13 09:01:52 2012 +0000
@@ -33,6 +33,7 @@
 
 #define SERIES_1
 #define SERIES_2
+#define WIFI
 
 // set to ATAP value of XBee. AP=2 is recommended
 #define ATAP 2
@@ -48,7 +49,9 @@
 // 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 MAX_FRAME_DATA_SIZE 110
+#define MAX_FRAME_DATA_SIZE 1520
+#define MAX_RXBUF_SIZE 32
 
 #define BROADCAST_ADDRESS 0xffff
 #define ZB_BROADCAST_ADDRESS 0xfffe
@@ -182,7 +185,7 @@
      * 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();
+    uint16_t getFrameDataLength();
     void setFrameData(uint8_t* frameDataPtr);
     /**
      * Returns the buffer that contains the response.
@@ -194,7 +197,7 @@
      */
     uint8_t* getFrameData();
 
-    void setFrameLength(uint8_t frameLength);
+    void setFrameLength(uint16_t frameLength);
     // to support future 65535 byte packets I guess
     /**
      * Returns the length of the packet
@@ -283,7 +286,7 @@
     uint8_t _msbLength;
     uint8_t _lsbLength;
     uint8_t _checksum;
-    uint8_t _frameLength;
+    uint16_t _frameLength;
     bool _complete;
     uint8_t _errorCode;
 };
@@ -348,7 +351,7 @@
     /**
      * Returns the length of the payload
      */
-    virtual uint8_t getDataLength() = 0;
+    virtual uint16_t getDataLength() = 0;
     /**
      * Returns the position in the frame data where the data begins
      */
@@ -382,7 +385,7 @@
     XBeeAddress64& getRemoteAddress64();
     uint16_t getRemoteAddress16();
     uint8_t getOption();
-    virtual uint8_t getDataLength();
+    virtual uint16_t getDataLength();
     // frame position where data starts
     virtual uint8_t getDataOffset();
 private:
@@ -444,7 +447,7 @@
     uint8_t getOption();
     bool isAddressBroadcast();
     bool isPanBroadcast();
-    virtual uint8_t getDataLength();
+    virtual uint16_t getDataLength();
     virtual uint8_t getDataOffset();
     virtual uint8_t getRssiOffset() = 0;
 };
@@ -558,7 +561,7 @@
         /**
          * Returns the length of the command value array.
          */
-        uint8_t getValueLength();
+        uint16_t getValueLength();
         /**
          * Returns true if status equals AT_OK
          */
@@ -588,7 +591,7 @@
         /**
          * Returns the length of the command value array.
          */
-        uint8_t getValueLength();
+        uint16_t getValueLength();
         /**
          * Returns the 16-bit address of the remote radio
          */
@@ -639,11 +642,11 @@
      * 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;
+    virtual uint8_t getFrameData(uint16_t pos) = 0;
     /**
      * Returns the size of the api frame (not including frame id or api id or checksum).
      */
-    virtual uint8_t getFrameDataLength() = 0;
+    virtual uint16_t getFrameDataLength() = 0;
     //void reset();
 protected:
     void setApiId(uint8_t apiId);
@@ -677,7 +680,7 @@
 class XBee {
 public:
     XBee(PinName p_tx, PinName p_rx);
-    XBee(PinName p_tx, PinName p_rx, PinName p_cts);
+    XBee(PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts);
     // for eclipse dev only
 //    void setSerial(HardwareSerial serial);
     /**
@@ -723,21 +726,27 @@
      * Returns a sequential frame id between 1 and 255
      */
     uint8_t getNextFrameId();
+    
+    void isr_recv ();
+    int getbuf ();
+    int bufreadable ();
 private:
     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;
+    uint16_t _pos, _epos;
     // last byte read
     uint8_t b;
-    uint8_t _checksumTotal;
+    uint16_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];
     Serial _xbee;
-    DigitalIn *_cts;
+    char _rxbuf[MAX_RXBUF_SIZE];
+    int _rxaddr_w, _rxaddr_r;
+    bool _rts;
 };
 
 /**
@@ -745,7 +754,7 @@
  */
 class PayloadRequest : public XBeeRequest {
 public:
-    PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint8_t payloadLength);
+    PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint16_t payloadLength);
     /**
      * Returns the payload of the packet, if not null
      */
@@ -757,16 +766,16 @@
     /**
      * Returns the length of the payload array, as specified by the user.
      */
-    uint8_t getPayloadLength();
+    uint16_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);
+    void setPayloadLength(uint16_t payloadLength);
 private:
     uint8_t* _payloadPtr;
-    uint8_t _payloadLength;
+    uint16_t _payloadLength;
 };
 
 #ifdef SERIES_1
@@ -781,11 +790,11 @@
  */
 class Tx16Request : public PayloadRequest {
 public:
-    Tx16Request(uint16_t addr16, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId);
+    Tx16Request(uint16_t addr16, uint8_t option, uint8_t *payload, uint16_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);
+    Tx16Request(uint16_t addr16, uint8_t *payload, uint16_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.
@@ -795,8 +804,8 @@
     void setAddress16(uint16_t addr16);
     uint8_t getOption();
     void setOption(uint8_t option);
-    virtual uint8_t getFrameData(uint8_t pos);
-    virtual uint8_t getFrameDataLength();
+    virtual uint8_t getFrameData(uint16_t pos);
+    virtual uint16_t getFrameDataLength();
 protected:
 private:
     uint16_t _addr16;
@@ -813,11 +822,11 @@
  */
 class Tx64Request : public PayloadRequest {
 public:
-    Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId);
+    Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *payload, uint16_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);
+    Tx64Request(XBeeAddress64 &addr64, uint8_t *payload, uint16_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.
@@ -828,8 +837,8 @@
     // TODO move option to superclass
     uint8_t getOption();
     void setOption(uint8_t option);
-    virtual uint8_t getFrameData(uint8_t pos);
-    virtual uint8_t getFrameDataLength();
+    virtual uint8_t getFrameData(uint16_t pos);
+    virtual uint16_t getFrameDataLength();
 private:
     XBeeAddress64 _addr64;
     uint8_t _option;
@@ -857,8 +866,8 @@
     /**
      * 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);
+    ZBTxRequest(XBeeAddress64 &addr64, uint8_t *payload, uint16_t payloadLength);
+    ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *payload, uint16_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.
@@ -874,8 +883,8 @@
     void setOption(uint8_t option);
 protected:
     // declare virtual functions
-    virtual uint8_t getFrameData(uint8_t pos);
-    virtual uint8_t getFrameDataLength();
+    virtual uint8_t getFrameData(uint16_t pos);
+    virtual uint16_t getFrameDataLength();
 private:
     XBeeAddress64 _addr64;
     uint16_t _addr16;
@@ -894,8 +903,8 @@
     AtCommandRequest();
     AtCommandRequest(uint8_t *command);
     AtCommandRequest(uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength);
-    virtual uint8_t getFrameData(uint8_t pos);
-    virtual uint8_t getFrameDataLength();
+    virtual uint8_t getFrameData(uint16_t pos);
+    virtual uint16_t getFrameDataLength();
     uint8_t* getCommand();
     void setCommand(uint8_t* command);
     uint8_t* getCommandValue();
@@ -946,8 +955,8 @@
     void setRemoteAddress64(XBeeAddress64 &remoteAddress64);
     bool getApplyChanges();
     void setApplyChanges(bool applyChanges);
-    virtual uint8_t getFrameData(uint8_t pos);
-    virtual uint8_t getFrameDataLength();
+    virtual uint8_t getFrameData(uint16_t pos);
+    virtual uint16_t getFrameDataLength();
     static XBeeAddress64 broadcastAddress64;
 //    static uint16_t broadcast16Address;
 private:
--- a/XBeeWiFi.cpp	Thu Mar 08 17:41:29 2012 +0000
+++ b/XBeeWiFi.cpp	Tue Mar 13 09:01:52 2012 +0000
@@ -19,7 +19,7 @@
 #define REVERSE_ENDIAN(x) (uint16_t)(((uint16_t)x >> 8) | ((uint16_t)x << 8))
 
 #ifdef USE_WIFICLASS
-XBeeWiFi::XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts) : XBee(p_tx, p_rx, p_cts) {
+XBeeWiFi::XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts) : XBee(p_tx, p_rx, p_cts, p_rts) {
 }
 
 int XBeeWiFi::setup (int security, const char *ssid, const char *pin) {
@@ -86,6 +86,36 @@
     return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
 }
 
+int XBeeWiFi::baud (int b) {
+    // RESET
+    uint8_t cmd[2] = {'B', 'D'};
+    char val[4];
+    AtCommandRequest atRequest;
+    int r, len;
+
+    if (b < 0x100) {
+        val[0] = b;
+        len = 1;
+    } else {
+        val[0] = (b >> 24) & 0xff;
+        val[1] = (b >> 16) & 0xff;
+        val[2] = (b >> 8) & 0xff;
+        val[3] = b & 0xff;
+        len = 4;
+    }
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue((uint8_t*)val);
+    atRequest.setCommandValueLength(len);
+    atRequest.setFrameId(getNextFrameId());
+    send(atRequest);
+    r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
+
+    if (r == 0) {
+        begin(b);
+    }
+    return r;
+}
+
 int XBeeWiFi::setAddress () {
     // DHCP
     uint8_t cmd[2] = {'M', 'A'};
@@ -281,9 +311,11 @@
     return 0;
 }
 
+// *** Note: wifi is turned off when XBee send the port 53 udp packet.
 int XBeeWiFi::getHostByName (const char* name, IpAddr &addr) {
-    char buf[1024];
-    int i, r, len;
+    Timer timeout;
+    char buf[600];
+    int r, len;
     uint8_t cmd[2] = {'C', '0'};
     char val[2];
     IPv4TransmitRequest dnsRequest;
@@ -294,7 +326,7 @@
         addr = IpAddr(127, 0, 0, 1);
         return 0;
     }
-    
+/*
     // bind src port
     val[0] = (DNS_SRC_PORT >> 8) & 0xff;
     val[1] = DNS_SRC_PORT & 0xff;
@@ -305,7 +337,7 @@
     send(atRequest);
     r = getWiResponse(AT_COMMAND_RESPONSE);
     DBG("wifi C0: %d\r\n", r);
-
+*/
     // send DNS request
     len = createDnsRequest(name, buf);
     dnsRequest.setAddress(_nameserver);
@@ -314,18 +346,23 @@
     dnsRequest.setProtocol(PROTOCOL_UDP);
     dnsRequest.setPayload((uint8_t*)buf);
     dnsRequest.setPayloadLength(len);
-    for (i = 0; i < DNS_TIMEOUT; i ++) {
+    
+    // wait responce
+    timeout.reset();
+    timeout.start();
+    while (timeout.read_ms() < DNS_TIMEOUT) {
         dnsRequest.setFrameId(getNextFrameId());
         send(dnsRequest);
 
         r = getWiResponse(TX_STATUS_RESPONSE, dnsRequest.getFrameId());
         DBG("wifi TX: %d\r\n", r);
 
-        if (r == 0) {
+        if (r >= 0) {
             // recv DNS request
             r = getWiResponse(IPv4_RX_FRAME, 0, 3000);
             DBG("wifi RX: %d\r\n", r);
             if (r >= 0) {
+                timeout.stop();
                 getResponse().getAtCommandResponse(atResponse);
                 return getDnsResponse(atResponse.getValue() + 6, atResponse.getValueLength() - 6, addr);
             }
@@ -333,6 +370,7 @@
             break;
         }
     }
+    timeout.stop();
 
     return -1;
 }
@@ -418,7 +456,7 @@
 IPv4TransmitRequest::IPv4TransmitRequest() : PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
 }
 
-IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId): PayloadRequest(IPv4_TRANSMIT_REQUEST, frameId, data, dataLength) {
+IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId): PayloadRequest(IPv4_TRANSMIT_REQUEST, frameId, data, dataLength) {
     _dstAddr = dstAddr;
     _dstPort = dstPort;
     _srcPort = srcPort;
@@ -426,7 +464,7 @@
     _option = option;
 }
 
-IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint8_t dataLength): PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
+IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint16_t dataLength): PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
     _dstAddr = dstAddr;
     _dstPort = dstPort;
     _srcPort = 0x270f;
@@ -434,7 +472,7 @@
     _option = 0;
 }
 
-uint8_t IPv4TransmitRequest::getFrameData(uint8_t pos) {
+uint8_t IPv4TransmitRequest::getFrameData(uint16_t pos) {
     if (pos == 0) {
         return _dstAddr[0];
     } else if (pos == 1) {
@@ -460,7 +498,7 @@
     }
 }
 
-uint8_t IPv4TransmitRequest::getFrameDataLength() {
+uint16_t IPv4TransmitRequest::getFrameDataLength() {
     return IPv4_TRANSMIT_REQUEST_API_LENGTH + getPayloadLength();
 }
 
@@ -518,32 +556,35 @@
 }
 
 
+IPV4RxFrame::IPV4RxFrame () {
+}
+
 IpAddr& IPV4RxFrame::getSrcAddress() {
-    _srcAddr = IpAddr(getFrameData()[4], getFrameData()[5], getFrameData()[6], getFrameData()[7]);
+    _srcAddr = IpAddr(getFrameData()[0], getFrameData()[1], getFrameData()[2], getFrameData()[3]);
     return _srcAddr;
 }
 
 uint16_t IPV4RxFrame::getDstPort() {
-    return (getFrameData()[8] << 8) + getFrameData()[9];
+    return (getFrameData()[4] << 8) + getFrameData()[5];
 }
 
 uint16_t IPV4RxFrame::getSrcPort() {
-    return (getFrameData()[10] << 8) + getFrameData()[11];
+    return (getFrameData()[6] << 8) + getFrameData()[7];
 }
 
 uint8_t IPV4RxFrame::getProtocol() {
-    return getFrameData()[12];
+    return getFrameData()[8];
 }
 
 uint8_t IPV4RxFrame::getStatus() {
-    return getFrameData()[13];
+    return getFrameData()[9];
 }
 
 // markers to read data from packet array.  this is the index, so the 12th item in the array
 uint8_t IPV4RxFrame::getDataOffset() {
-    return 14;
+    return 10;
 }
 
-uint8_t IPV4RxFrame::getDataLength() {
+uint16_t IPV4RxFrame::getDataLength() {
     return getPacketLength() - getDataOffset() - 1;
 }
--- a/XBeeWiFi.h	Thu Mar 08 17:41:29 2012 +0000
+++ b/XBeeWiFi.h	Tue Mar 13 09:01:52 2012 +0000
@@ -72,8 +72,8 @@
 #define DNS_CLASS_IN 1
 
 #define DNS_PORT 53
-#define DNS_SRC_PORT 1234
-#define DNS_TIMEOUT 5 // x 3s
+#define DNS_SRC_PORT 10053
+#define DNS_TIMEOUT 15000 // ms
 
 struct DNSHeader {
         uint16_t id; 
@@ -104,21 +104,26 @@
  */
 class XBeeWiFi : public XBee {
 public:
-    XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts);
+    XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts);
 
     int setup (int security, const char *ssid, const char *pin);
     int setup (const char *ssid);
     int reset ();
+    int baud (int b);
     int setAddress ();
     int setAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver);
     int getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver);
     int setTimeout (int timeout);
     int getStatus ();
-    int getWiResponse (int apiId, int frameid = 0, int timeout = 1500);
+    int getWiResponse (int apiId, int frameid = 0, int timeout = 3000);
 #ifdef USE_WIFIDNS
     int setNameserver (IpAddr &nameserver);
     int getHostByName (const char* name, IpAddr &addr);
 #endif
+    /**
+     * Call with instance of AtCommandResponse only if getApiId() == AT_COMMAND_RESPONSE
+     */
+//    void getIPV4RxFrame (XBeeResponse &responses);
 
 protected:
     int getWiAddr (IpAddr &ipaddr);
@@ -140,8 +145,8 @@
     /**
      * Creates a unicast IPv4TransmitRequest with the DEFAULT_FRAME_ID
      */
-    IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId);
-    IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint8_t dataLength);
+    IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId);
+    IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint16_t dataLength);
     /**
      * 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.
@@ -159,8 +164,8 @@
     void setOption(uint8_t option);
 protected:
     // declare virtual functions
-    virtual uint8_t getFrameData(uint8_t pos);
-    virtual uint8_t getFrameDataLength();
+    virtual uint8_t getFrameData(uint16_t pos);
+    virtual uint16_t getFrameDataLength();
 private:
     IpAddr _dstAddr;
     uint16_t _dstPort;
@@ -190,7 +195,7 @@
     uint16_t getSrcPort();
     uint8_t getProtocol();
     uint8_t getStatus();
-    virtual uint8_t getDataLength();
+    virtual uint16_t getDataLength();
     // frame position where data starts
     virtual uint8_t getDataOffset();
 private: