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
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