Poerting the Xbee library to use teh wifi functionality of the LPC4088.
Dependents: XBee_WiFi_EA_LPC4088
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;