Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of XBee by
Revision 3:8573b122fa84, committed 2012-03-08
- Comitter:
- okini3939
- Date:
- Thu Mar 08 17:41:29 2012 +0000
- Parent:
- 2:6efb3541af61
- Child:
- 4:f6d73acc1f75
- Commit message:
Changed in this revision
--- 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