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:
Thu Mar 08 17:41:29 2012 +0000
Parent:
2:6efb3541af61
Child:
4:f6d73acc1f75
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
dbg.h Show annotated file Show diff for this revision Revisions of this file
--- a/XBee.cpp	Fri Jul 29 16:22:15 2011 +0000
+++ b/XBee.cpp	Thu Mar 08 17:41:29 2012 +0000
@@ -21,6 +21,13 @@
  * along with XBee-Arduino.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/** @file
+ * @brief XBee library for mbed
+ */
+
+//#define DEBUG
+#include "dbg.h"
+
 #include "mbed.h"
 #include "XBee.h"
 
@@ -666,6 +673,18 @@
     _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) {
+    _pos = 0;
+    _escape = false;
+    _checksumTotal = 0;
+    _nextFrameId = 0;
+    _cts = new DigitalIn(p_cts);
 
     _response.init();
     _response.setFrameData(_responseFrameData);
@@ -727,6 +746,7 @@
 
     while (int((millis() - start)) < timeout) {
 */
+    t.reset();
     t.start();
     while (t.read_ms() < timeout) {
          readPacket();
@@ -772,6 +792,7 @@
                 continue;
             }
         }
+        DBG("%02x_", b);
 
         if (_escape == true) {
             b = 0x20 ^ b;
@@ -1348,16 +1369,21 @@
     // send packet
     Serial.flush();
 */
+    DBG("\r\n");
 }
 
 void XBee::sendByte(uint8_t b, bool escape) {
 
     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	Fri Jul 29 16:22:15 2011 +0000
+++ b/XBee.h	Thu Mar 08 17:41:29 2012 +0000
@@ -21,6 +21,10 @@
  * along with XBee-Arduino.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/** @file
+ * @brief XBee library for mbed
+ */
+
 #ifndef XBee_h
 #define XBee_h
 
@@ -673,6 +677,7 @@
 class XBee {
 public:
     XBee(PinName p_tx, PinName p_rx);
+    XBee(PinName p_tx, PinName p_rx, PinName p_cts);
     // for eclipse dev only
 //    void setSerial(HardwareSerial serial);
     /**
@@ -732,6 +737,7 @@
     // 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;
 };
 
 /**
--- a/XBeeWiFi.cpp	Fri Jul 29 16:22:15 2011 +0000
+++ b/XBeeWiFi.cpp	Thu Mar 08 17:41:29 2012 +0000
@@ -5,9 +5,12 @@
  */
 
 /** @file
- * @brief Weather Station
+ * @brief XBee Wi-Fi library for mbed
  */
 
+//#define DEBUG
+#include "dbg.h"
+
 #include "mbed.h"
 #include "XBee.h"
 #include "XBeeWiFi.h"
@@ -16,44 +19,53 @@
 #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) : XBee(p_tx, p_rx) {
+XBeeWiFi::XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts) : XBee(p_tx, p_rx, p_cts) {
 }
 
 int XBeeWiFi::setup (int security, const char *ssid, const char *pin) {
-    int len;
+    int len, r;
     uint8_t cmd[2], val[32];
     AtCommandRequest atRequest;
 
+    // SSID
+    memcpy(cmd, "ID", 2);
+    len = strlen(ssid);
+    memcpy(val, ssid, len);
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue(val);
+    atRequest.setCommandValueLength(len);
+    atRequest.setFrameId(getNextFrameId());
+    send(atRequest);
+    r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
+    DBG("wifi ID: %d\r\n", r);
+    if (r < 0) return -1;
+
+    if (security != SECURITY_OPEN) {
+        // PIN
+        memcpy(cmd, "PK", 2);
+        len = strlen(pin);
+        memcpy(val, pin, len);
+        atRequest.setCommand(cmd);
+        atRequest.setCommandValue(val);
+        atRequest.setCommandValueLength(len);
+        atRequest.setFrameId(getNextFrameId());
+        send(atRequest);
+        r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
+        DBG("wifi PK: %d\r\n", r);
+        if (r < 0) return -1;
+    }
+
     // security type
     memcpy(cmd, "EE", 2);
     val[0] = security;
     atRequest.setCommand(cmd);
     atRequest.setCommandValue(val);
     atRequest.setCommandValueLength(1);
+    atRequest.setFrameId(getNextFrameId());
     send(atRequest);
-    getWiResponse(AT_COMMAND_RESPONSE);
-
-    if (security != SECURITY_OPEN) {
-        // SSID
-        memcpy(cmd, "ID", 2);
-        len = strlen(ssid);
-        memcpy(val, ssid, len);
-        atRequest.setCommand(cmd);
-        atRequest.setCommandValue(val);
-        atRequest.setCommandValueLength(len);
-        send(atRequest);
-        getWiResponse(AT_COMMAND_RESPONSE);
-
-        // PIN
-        memcpy(cmd, "PK", 2);
-        len = strlen(pin);
-        memcpy(val, pin, len);
-        atRequest.setCommand(cmd);
-        atRequest.setCommandValue(val);
-        atRequest.setCommandValueLength(len);
-        send(atRequest);
-        getWiResponse(AT_COMMAND_RESPONSE);
-    }
+    r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
+    DBG("wifi EE: %d\r\n", r);
+    if (r < 0) return -1;
 
     return 0;
 }
@@ -64,13 +76,14 @@
 
 int XBeeWiFi::reset () {
     // RESET
-    uint8_t cmd[2] = {'N', 'R'};
+    uint8_t cmd[2] = {'N', 'R'}; // Network reset
+//    uint8_t cmd[2] = {'F', 'R'}; // Software reset
     AtCommandRequest atRequest;
 
     atRequest.setCommand(cmd);
+    atRequest.setFrameId(getNextFrameId());
     send(atRequest);
-
-    return getWiResponse(AT_COMMAND_RESPONSE);
+    return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
 }
 
 int XBeeWiFi::setAddress () {
@@ -82,9 +95,10 @@
     atRequest.setCommand(cmd);
     atRequest.setCommandValue((uint8_t*)val);
     atRequest.setCommandValueLength(1);
+    atRequest.setFrameId(getNextFrameId());
     send(atRequest);
 
-    return getWiResponse(AT_COMMAND_RESPONSE);
+    return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
 }
 
 int XBeeWiFi::setAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
@@ -98,8 +112,9 @@
     atRequest.setCommand(cmd);
     atRequest.setCommandValue((uint8_t*)val);
     atRequest.setCommandValueLength(1);
+    atRequest.setFrameId(getNextFrameId());
     send(atRequest);
-    getWiResponse(AT_COMMAND_RESPONSE);
+    getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
 
     // IP address
     memcpy(cmd, "MY", 2);
@@ -107,8 +122,9 @@
     atRequest.setCommand(cmd);
     atRequest.setCommandValue((uint8_t*)val);
     atRequest.setCommandValueLength(strlen(val));
+    atRequest.setFrameId(getNextFrameId());
     send(atRequest);
-    getWiResponse(AT_COMMAND_RESPONSE);
+    getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
 
     // sub netmask
     memcpy(cmd, "NK", 2);
@@ -116,8 +132,9 @@
     atRequest.setCommand(cmd);
     atRequest.setCommandValue((uint8_t*)val);
     atRequest.setCommandValueLength(strlen(val));
+    atRequest.setFrameId(getNextFrameId());
     send(atRequest);
-    getWiResponse(AT_COMMAND_RESPONSE);
+    getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
 
     // default gateway
     memcpy(cmd, "GW", 2);
@@ -125,8 +142,9 @@
     atRequest.setCommand(cmd);
     atRequest.setCommandValue((uint8_t*)val);
     atRequest.setCommandValueLength(strlen(val));
+    atRequest.setFrameId(getNextFrameId());
     send(atRequest);
-    getWiResponse(AT_COMMAND_RESPONSE);
+    getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
 
     // name server
     _nameserver = nameserver;
@@ -134,6 +152,63 @@
     return 0;
 }
 
+int XBeeWiFi::getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
+    int r;
+    uint8_t cmd[2];
+    AtCommandRequest atRequest;
+    AtCommandResponse atResponse;
+
+    memcpy(cmd, "MY", 2);
+    atRequest.setCommand(cmd);
+    atRequest.clearCommandValue();
+    atRequest.setFrameId(getNextFrameId());
+    send(atRequest);
+    r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
+    DBG("wifi MY: %d\r\n", r);
+    if (r >= 0) {
+        r = getWiAddr(ipaddr);
+    }
+
+    memcpy(cmd, "MK", 2);
+    atRequest.setCommand(cmd);
+    atRequest.clearCommandValue();
+    atRequest.setFrameId(getNextFrameId());
+    send(atRequest);
+    r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
+    DBG("wifi MK: %d\r\n", r);
+    if (r >= 0) {
+        r = getWiAddr(netmask);
+    }
+
+    memcpy(cmd, "GW", 2);
+    atRequest.setCommand(cmd);
+    atRequest.clearCommandValue();
+    atRequest.setFrameId(getNextFrameId());
+    send(atRequest);
+    r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
+    DBG("wifi GW: %d\r\n", r);
+    if (r >= 0) {
+        r = getWiAddr(gateway);
+    }
+
+    nameserver = _nameserver;
+
+    return 0;
+}
+
+int XBeeWiFi::getWiAddr (IpAddr &ipaddr) {
+    int ip1, ip2, ip3, ip4;
+    AtCommandResponse atResponse;
+
+    getResponse().getAtCommandResponse(atResponse);
+    if (atResponse.isOk() && atResponse.getValueLength() >= 7) {
+        sscanf((char*)atResponse.getValue(), "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
+        ipaddr = IpAddr(ip1, ip2, ip3, ip4);
+        return 0;
+    }
+    return -1;
+}
+
 int XBeeWiFi::setTimeout (int timeout) {
     // timeout
     uint8_t cmd[2] = {'T', 'P'};
@@ -144,6 +219,7 @@
     atRequest.setCommand(cmd);
     atRequest.setCommandValue((uint8_t*)val);
     atRequest.setCommandValueLength(1);
+    atRequest.setFrameId(getNextFrameId());
     send(atRequest);
 
     return getWiResponse(AT_COMMAND_RESPONSE);
@@ -155,33 +231,44 @@
     AtCommandRequest atRequest;
 
     atRequest.setCommand(cmd);
+    atRequest.setFrameId(getNextFrameId());
     send(atRequest);
 
-    return getWiResponse(AT_COMMAND_RESPONSE);
+    return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
 }
 
-int XBeeWiFi::getWiResponse (int apiId, int timeout) {
+int XBeeWiFi::getWiResponse (int apiId, int frameid, int timeout) {
     AtCommandResponse atResponse;
 
     if (readPacket(timeout)) {
+        if (frameid && frameid != getResponse().getFrameData()[0]) {
+            DBG("Expected AT response but got %x (frame %d)\r\n", getResponse().getApiId(), getResponse().getFrameData()[0]);
+            if (! readPacket(timeout)) return -1;
+            DBG("Retry ok\r\n");
+        }
+
         if (getResponse().getApiId() == apiId) {
             getResponse().getAtCommandResponse(atResponse);
 
+            if (getResponse().getApiId() == IPv4_RX_FRAME) {
+                return 0;
+            } else
             if (atResponse.isOk()) {
 
+//                if (getResponse().getFrameDataLength() > 4) {
                 return atResponse.getValue()[0];
 
             } else {
-                printf("Command return error code: %x\r\n", atResponse.getStatus());
+                DBG("Command return error code: %x\r\n", atResponse.getStatus());
             }
         } else {
-            printf("Expected AT response but got %x\r\n", getResponse().getApiId());
+            DBG("Expected AT response but got %x\r\n", getResponse().getApiId());
         }
     } else {
         if (getResponse().isError()) {
-            printf("Error reading packet.  Error code: %x\r\n", getResponse().getErrorCode());  
+            DBG("Error reading packet.  Error code: %x\r\n", getResponse().getErrorCode());  
         } else {
-            printf("No response from radio");  
+            DBG("No response from radio\r\n");  
         }
     }
 
@@ -189,9 +276,16 @@
 }
 
 #ifdef USE_WIFIDNS
+int XBeeWiFi::setNameserver (IpAddr &nameserver) {
+    _nameserver = nameserver;
+    return 0;
+}
+
 int XBeeWiFi::getHostByName (const char* name, IpAddr &addr) {
     char buf[1024];
-    int len;
+    int i, r, len;
+    uint8_t cmd[2] = {'C', '0'};
+    char val[2];
     IPv4TransmitRequest dnsRequest;
     AtCommandRequest atRequest;
     AtCommandResponse atResponse;
@@ -200,25 +294,43 @@
         addr = IpAddr(127, 0, 0, 1);
         return 0;
     }
-
-    len = createDnsRequest(name, buf);
+    
+    // bind src port
+    val[0] = (DNS_SRC_PORT >> 8) & 0xff;
+    val[1] = DNS_SRC_PORT & 0xff;
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue((uint8_t*)val);
+    atRequest.setCommandValueLength(2);
+    atRequest.setFrameId(getNextFrameId());
+    send(atRequest);
+    r = getWiResponse(AT_COMMAND_RESPONSE);
+    DBG("wifi C0: %d\r\n", r);
 
     // send DNS request
+    len = createDnsRequest(name, buf);
     dnsRequest.setAddress(_nameserver);
-    dnsRequest.setDstPort(53);
-    dnsRequest.setSrcPort(1243);
+    dnsRequest.setDstPort(DNS_PORT);
+    dnsRequest.setSrcPort(DNS_SRC_PORT);
     dnsRequest.setProtocol(PROTOCOL_UDP);
     dnsRequest.setPayload((uint8_t*)buf);
     dnsRequest.setPayloadLength(len);
-    send(dnsRequest);
+    for (i = 0; i < DNS_TIMEOUT; i ++) {
+        dnsRequest.setFrameId(getNextFrameId());
+        send(dnsRequest);
+
+        r = getWiResponse(TX_STATUS_RESPONSE, dnsRequest.getFrameId());
+        DBG("wifi TX: %d\r\n", r);
 
-    if (getWiResponse(IPv4_TRANSMIT_STATUS) == 0) {
-        // recv DNS request
-        if (getWiResponse(IPv4_RX_FRAME, 30000) != -1) {
-            getResponse().getAtCommandResponse(atResponse);
-            if (atResponse.isOk()) {
-                return getDnsResponse(atResponse.getValue(), atResponse.getValueLength(), addr);
+        if (r == 0) {
+            // recv DNS request
+            r = getWiResponse(IPv4_RX_FRAME, 0, 3000);
+            DBG("wifi RX: %d\r\n", r);
+            if (r >= 0) {
+                getResponse().getAtCommandResponse(atResponse);
+                return getDnsResponse(atResponse.getValue() + 6, atResponse.getValueLength() - 6, addr);
             }
+        } else {
+            break;
         }
     }
 
@@ -238,33 +350,32 @@
     dnsHeader->answers = 0;
     dnsHeader->authorities = 0;
     dnsHeader->additional = 0;
-    len = sizeof(dnsHeader);
 
     // DNS question
-    num = (int)strchr(name, '.');
-    while (num) {
+    len = sizeof(DNSHeader);
+    while ((num = (int)strchr(name, '.')) != NULL) {
         num = num - (int)name;
         buf[len] = num;
         len ++;
         strncpy(&buf[len], name, num); 
-        name = name + num;
+        name = name + num + 1;
         len = len + num;
-        num = (int)strchr(name, '.');
     }
 
-    num = (int)strlen(name);
-    if (num) {
+    if ((num = strlen(name)) != NULL) {
         buf[len] = num;
         len ++; 
         strncpy(&buf[len], name, num); 
-        len = len + num + 1;
+        len = len + num;
     }
+    buf[len] = 0;
+    len ++; 
 
     dnsEnd = (DnsQuestionEnd*)&buf[len];
     dnsEnd->type = REVERSE_ENDIAN(DNS_QUERY_A);
     dnsEnd->clas = REVERSE_ENDIAN(DNS_CLASS_IN);
 
-    return len + sizeof(dnsEnd);
+    return len + sizeof(DnsQuestionEnd);
 }
 
 int XBeeWiFi::getDnsResponse (const uint8_t *buf, int len, IpAddr &addr) {
@@ -279,7 +390,7 @@
     }
 
     // skip question
-    for (i = sizeof(dnsHeader); buf[i] && i < len; i ++);
+    for (i = sizeof(DNSHeader); buf[i] && i < len; i ++);
     i = i + 1 + sizeof(DnsQuestionEnd);
 
     // DNS answer
@@ -289,7 +400,7 @@
             return -1;
         }
 
-        i = i + sizeof(dnsAnswer);
+        i = i + sizeof(DnsAnswer);
         if (dnsAnswer->type == REVERSE_ENDIAN(DNS_QUERY_A)) {
             addr = IpAddr(buf[i], buf[i + 1], buf[i + 2], buf[i + 3]);
             return 0;
--- a/XBeeWiFi.h	Fri Jul 29 16:22:15 2011 +0000
+++ b/XBeeWiFi.h	Thu Mar 08 17:41:29 2012 +0000
@@ -5,7 +5,7 @@
  */
 
 /** @file
- * @brief Weather Station
+ * @brief XBee Wi-Fi library for mbed
  */
 
 #ifndef XBeeWiFi_h
@@ -16,8 +16,8 @@
 #include "XBee.h"
 #include <inttypes.h>
 
-#undef USE_WIFICLASS
-#undef USE_WIFIDNS
+#define USE_WIFICLASS
+#define USE_WIFIDNS
 
 // the non-variable length of the frame data (not including frame id or api id or variable data size (e.g. payload, at command set value)
 #define IPv4_TRANSMIT_REQUEST_API_LENGTH 10
@@ -53,8 +53,13 @@
 
 /// modem status
 #define JOINED_AP 0
+#define INITIALIZATION 0x01
+#define SSID_NOT_FOUND 0x22
 #define SSID_NOT_CONFIGURED 0x23
-#define JOINING_AP 0xff
+#define JOIN_FAILED 0x27
+#define WAITING_IPADDRESS 0x41
+#define WAITING_SOCKETS 0x42
+#define SCANNING_SSID 0xff
 
 /// dns
 #define DNS_QUERY_A 1
@@ -66,6 +71,10 @@
 #define DNS_QUERY_ANY 255
 #define DNS_CLASS_IN 1
 
+#define DNS_PORT 53
+#define DNS_SRC_PORT 1234
+#define DNS_TIMEOUT 5 // x 3s
+
 struct DNSHeader {
         uint16_t id; 
         uint16_t flags; 
@@ -95,21 +104,24 @@
  */
 class XBeeWiFi : public XBee {
 public:
-    XBeeWiFi (PinName p_tx, PinName p_rx);
+    XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts);
 
     int setup (int security, const char *ssid, const char *pin);
     int setup (const char *ssid);
     int reset ();
     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);
 #ifdef USE_WIFIDNS
+    int setNameserver (IpAddr &nameserver);
     int getHostByName (const char* name, IpAddr &addr);
 #endif
 
 protected:
-    int getWiResponse (int apiId, int timeout = 1500);
+    int getWiAddr (IpAddr &ipaddr);
 #ifdef USE_WIFIDNS
     int createDnsRequest (const char* name, char *buf);
     int getDnsResponse (const uint8_t *buf, int len, IpAddr &addr);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dbg.h	Thu Mar 08 17:41:29 2012 +0000
@@ -0,0 +1,7 @@
+//#define DEBUG
+
+#ifdef DEBUG 
+#define DBG(...) printf("" __VA_ARGS__) 
+#else 
+#define DBG(...) 
+#endif