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
Diff: XBeeWiFi.cpp
- Revision:
- 3:8573b122fa84
- Parent:
- 2:6efb3541af61
- Child:
- 4:f6d73acc1f75
--- 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;