no changes

Fork of XBee by Suga koubou

Revision:
2:6efb3541af61
Child:
3:8573b122fa84
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/XBeeWiFi.cpp	Fri Jul 29 16:22:15 2011 +0000
@@ -0,0 +1,438 @@
+/**
+ * XBee Wi-Fi library for mbed
+ * Copyright (c) 2011 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief Weather Station
+ */
+
+#include "mbed.h"
+#include "XBee.h"
+#include "XBeeWiFi.h"
+#include "EthernetNetIf.h"
+
+#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) {
+}
+
+int XBeeWiFi::setup (int security, const char *ssid, const char *pin) {
+    int len;
+    uint8_t cmd[2], val[32];
+    AtCommandRequest atRequest;
+
+    // security type
+    memcpy(cmd, "EE", 2);
+    val[0] = security;
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue(val);
+    atRequest.setCommandValueLength(1);
+    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);
+    }
+
+    return 0;
+}
+
+int XBeeWiFi::setup (const char *ssid) {
+    return setup(SECURITY_OPEN, ssid, NULL);
+}
+
+int XBeeWiFi::reset () {
+    // RESET
+    uint8_t cmd[2] = {'N', 'R'};
+    AtCommandRequest atRequest;
+
+    atRequest.setCommand(cmd);
+    send(atRequest);
+
+    return getWiResponse(AT_COMMAND_RESPONSE);
+}
+
+int XBeeWiFi::setAddress () {
+    // DHCP
+    uint8_t cmd[2] = {'M', 'A'};
+    char val[1] = {0};
+    AtCommandRequest atRequest;
+
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue((uint8_t*)val);
+    atRequest.setCommandValueLength(1);
+    send(atRequest);
+
+    return getWiResponse(AT_COMMAND_RESPONSE);
+}
+
+int XBeeWiFi::setAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
+    uint8_t cmd[2];
+    char val[32];
+    AtCommandRequest atRequest;
+
+    // Static
+    memcpy(cmd, "MA", 2);
+    val[0] = 1;
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue((uint8_t*)val);
+    atRequest.setCommandValueLength(1);
+    send(atRequest);
+    getWiResponse(AT_COMMAND_RESPONSE);
+
+    // IP address
+    memcpy(cmd, "MY", 2);
+    sprintf(val, "%d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue((uint8_t*)val);
+    atRequest.setCommandValueLength(strlen(val));
+    send(atRequest);
+    getWiResponse(AT_COMMAND_RESPONSE);
+
+    // sub netmask
+    memcpy(cmd, "NK", 2);
+    sprintf(val, "%d.%d.%d.%d", netmask[0], netmask[1], netmask[2], netmask[3]);
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue((uint8_t*)val);
+    atRequest.setCommandValueLength(strlen(val));
+    send(atRequest);
+    getWiResponse(AT_COMMAND_RESPONSE);
+
+    // default gateway
+    memcpy(cmd, "GW", 2);
+    sprintf(val, "%d.%d.%d.%d", gateway[0], gateway[1], gateway[2], gateway[3]);
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue((uint8_t*)val);
+    atRequest.setCommandValueLength(strlen(val));
+    send(atRequest);
+    getWiResponse(AT_COMMAND_RESPONSE);
+
+    // name server
+    _nameserver = nameserver;
+
+    return 0;
+}
+
+int XBeeWiFi::setTimeout (int timeout) {
+    // timeout
+    uint8_t cmd[2] = {'T', 'P'};
+    char val[1];
+    AtCommandRequest atRequest;
+
+    val[0] = timeout;
+    atRequest.setCommand(cmd);
+    atRequest.setCommandValue((uint8_t*)val);
+    atRequest.setCommandValueLength(1);
+    send(atRequest);
+
+    return getWiResponse(AT_COMMAND_RESPONSE);
+}
+
+int XBeeWiFi::getStatus () {
+    // AI
+    uint8_t cmd[2] = {'A', 'I'};
+    AtCommandRequest atRequest;
+
+    atRequest.setCommand(cmd);
+    send(atRequest);
+
+    return getWiResponse(AT_COMMAND_RESPONSE);
+}
+
+int XBeeWiFi::getWiResponse (int apiId, int timeout) {
+    AtCommandResponse atResponse;
+
+    if (readPacket(timeout)) {
+        if (getResponse().getApiId() == apiId) {
+            getResponse().getAtCommandResponse(atResponse);
+
+            if (atResponse.isOk()) {
+
+                return atResponse.getValue()[0];
+
+            } else {
+                printf("Command return error code: %x\r\n", atResponse.getStatus());
+            }
+        } else {
+            printf("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());  
+        } else {
+            printf("No response from radio");  
+        }
+    }
+
+    return -1;
+}
+
+#ifdef USE_WIFIDNS
+int XBeeWiFi::getHostByName (const char* name, IpAddr &addr) {
+    char buf[1024];
+    int len;
+    IPv4TransmitRequest dnsRequest;
+    AtCommandRequest atRequest;
+    AtCommandResponse atResponse;
+
+    if (!strcmp(name, "localhost")) {
+        addr = IpAddr(127, 0, 0, 1);
+        return 0;
+    }
+
+    len = createDnsRequest(name, buf);
+
+    // send DNS request
+    dnsRequest.setAddress(_nameserver);
+    dnsRequest.setDstPort(53);
+    dnsRequest.setSrcPort(1243);
+    dnsRequest.setProtocol(PROTOCOL_UDP);
+    dnsRequest.setPayload((uint8_t*)buf);
+    dnsRequest.setPayloadLength(len);
+    send(dnsRequest);
+
+    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);
+            }
+        }
+    }
+
+    return -1;
+}
+
+int XBeeWiFi::createDnsRequest (const char* name, char *buf) {
+    struct DNSHeader *dnsHeader;
+    struct DnsQuestionEnd *dnsEnd;
+    int len, num;
+
+    // DNS header
+    dnsHeader = (DNSHeader*)buf;
+    dnsHeader->id = REVERSE_ENDIAN(0xdead);
+    dnsHeader->flags = REVERSE_ENDIAN(0x100);
+    dnsHeader->questions = REVERSE_ENDIAN(1);
+    dnsHeader->answers = 0;
+    dnsHeader->authorities = 0;
+    dnsHeader->additional = 0;
+    len = sizeof(dnsHeader);
+
+    // DNS question
+    num = (int)strchr(name, '.');
+    while (num) {
+        num = num - (int)name;
+        buf[len] = num;
+        len ++;
+        strncpy(&buf[len], name, num); 
+        name = name + num;
+        len = len + num;
+        num = (int)strchr(name, '.');
+    }
+
+    num = (int)strlen(name);
+    if (num) {
+        buf[len] = num;
+        len ++; 
+        strncpy(&buf[len], name, num); 
+        len = len + num + 1;
+    }
+
+    dnsEnd = (DnsQuestionEnd*)&buf[len];
+    dnsEnd->type = REVERSE_ENDIAN(DNS_QUERY_A);
+    dnsEnd->clas = REVERSE_ENDIAN(DNS_CLASS_IN);
+
+    return len + sizeof(dnsEnd);
+}
+
+int XBeeWiFi::getDnsResponse (const uint8_t *buf, int len, IpAddr &addr) {
+    int i;
+    struct DNSHeader *dnsHeader;
+    struct DnsAnswer *dnsAnswer;
+
+    // DNS header
+    dnsHeader = (DNSHeader*)buf;
+    if (REVERSE_ENDIAN(dnsHeader->id) != 0xdead || (REVERSE_ENDIAN(dnsHeader->flags) & 0x800f) != 0x8000) {
+        return -1;
+    }
+
+    // skip question
+    for (i = sizeof(dnsHeader); buf[i] && i < len; i ++);
+    i = i + 1 + sizeof(DnsQuestionEnd);
+
+    // DNS answer
+    while (i < len) {
+        dnsAnswer = (DnsAnswer*)&buf[i];
+        if (dnsAnswer->clas != REVERSE_ENDIAN(DNS_CLASS_IN)) {
+            return -1;
+        }
+
+        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;
+        }
+        i = i + dnsAnswer->length;
+    }
+
+    return -1;
+}
+#endif
+
+#endif
+
+
+IPv4TransmitRequest::IPv4TransmitRequest() : PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
+}
+
+IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId): PayloadRequest(IPv4_TRANSMIT_REQUEST, frameId, data, dataLength) {
+    _dstAddr = dstAddr;
+    _dstPort = dstPort;
+    _srcPort = srcPort;
+    _protocol = protocol;
+    _option = option;
+}
+
+IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint8_t dataLength): PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
+    _dstAddr = dstAddr;
+    _dstPort = dstPort;
+    _srcPort = 0x270f;
+    _protocol = PROTOCOL_UDP;
+    _option = 0;
+}
+
+uint8_t IPv4TransmitRequest::getFrameData(uint8_t pos) {
+    if (pos == 0) {
+        return _dstAddr[0];
+    } else if (pos == 1) {
+        return _dstAddr[1];
+    } else if (pos == 2) {
+        return _dstAddr[2];
+    } else if (pos == 3) {
+        return _dstAddr[3];
+    } else if (pos == 4) {
+        return (_dstPort >> 8) & 0xff;
+    } else if (pos == 5) {
+        return _dstPort & 0xff;
+    } else if (pos == 6) {
+        return (_srcPort >> 8) & 0xff;
+    } else if (pos == 7) {
+        return _srcPort & 0xff;
+    } else if (pos == 8) {
+        return _protocol;
+    } else if (pos == 9) {
+        return _option;
+    } else {
+        return getPayload()[pos - IPv4_TRANSMIT_REQUEST_API_LENGTH];
+    }
+}
+
+uint8_t IPv4TransmitRequest::getFrameDataLength() {
+    return IPv4_TRANSMIT_REQUEST_API_LENGTH + getPayloadLength();
+}
+
+IpAddr& IPv4TransmitRequest::getAddress() {
+    return _dstAddr;
+}
+
+uint16_t IPv4TransmitRequest::getDstPort() {
+    return _dstPort;
+}
+
+uint16_t IPv4TransmitRequest::getSrcPort() {
+    return _srcPort;
+}
+
+uint8_t IPv4TransmitRequest::getProtocol() {
+    return _protocol;
+}
+
+uint8_t IPv4TransmitRequest::getOption() {
+    return _option;
+}
+
+void IPv4TransmitRequest::setAddress(IpAddr &dstAddr) {
+    _dstAddr = dstAddr;
+}
+
+void IPv4TransmitRequest::setDstPort(uint16_t dstPort) {
+    _dstPort = dstPort;
+}
+
+void IPv4TransmitRequest::setSrcPort(uint16_t srcPort) {
+    _srcPort = srcPort;
+}
+
+void IPv4TransmitRequest::setProtocol(uint8_t protocol) {
+    _protocol = protocol;
+}
+
+void IPv4TransmitRequest::setOption(uint8_t option) {
+    _option = option;
+}
+
+
+Transmit_Status::Transmit_Status() : FrameIdResponse() {
+
+}
+
+uint8_t Transmit_Status::getStatus() {
+    return getFrameData()[1];
+}
+
+bool Transmit_Status::isSuccess() {
+    return getStatus() == SUCCESS;
+}
+
+
+IpAddr& IPV4RxFrame::getSrcAddress() {
+    _srcAddr = IpAddr(getFrameData()[4], getFrameData()[5], getFrameData()[6], getFrameData()[7]);
+    return _srcAddr;
+}
+
+uint16_t IPV4RxFrame::getDstPort() {
+    return (getFrameData()[8] << 8) + getFrameData()[9];
+}
+
+uint16_t IPV4RxFrame::getSrcPort() {
+    return (getFrameData()[10] << 8) + getFrameData()[11];
+}
+
+uint8_t IPV4RxFrame::getProtocol() {
+    return getFrameData()[12];
+}
+
+uint8_t IPV4RxFrame::getStatus() {
+    return getFrameData()[13];
+}
+
+// markers to read data from packet array.  this is the index, so the 12th item in the array
+uint8_t IPV4RxFrame::getDataOffset() {
+    return 14;
+}
+
+uint8_t IPV4RxFrame::getDataLength() {
+    return getPacketLength() - getDataOffset() - 1;
+}