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.
Dependents: device_server_udp led_sender_post XBee_API_ex1 XBee_API_ex2 ... more
Revision 2:6efb3541af61, committed 2011-07-29
- Comitter:
- okini3939
- Date:
- Fri Jul 29 16:22:15 2011 +0000
- Parent:
- 1:e3b2027e685c
- Child:
- 3:8573b122fa84
- Commit message:
Changed in this revision
--- a/XBee.cpp Mon Jan 10 16:32:18 2011 +0000
+++ b/XBee.cpp Fri Jul 29 16:22:15 2011 +0000
@@ -661,7 +661,7 @@
_response.reset();
}
-XBee::XBee(PinName p_tx, PinName p_rx): _xbee(p_tx, p_rx), _response(XBeeResponse()) {
+XBee::XBee(PinName p_tx, PinName p_rx): _xbee(p_tx, p_rx) {
_pos = 0;
_escape = false;
_checksumTotal = 0;
--- /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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/XBeeWiFi.h Fri Jul 29 16:22:15 2011 +0000
@@ -0,0 +1,188 @@
+/**
+ * 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
+ */
+
+#ifndef XBeeWiFi_h
+#define XBeeWiFi_h
+
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "XBee.h"
+#include <inttypes.h>
+
+#undef USE_WIFICLASS
+#undef 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
+
+/**
+ * Api Id constants
+ */
+#define IPv4_TRANSMIT_REQUEST 0x20
+#define IPv4_RX_FRAME 0xb0
+#define IPv4_TRANSMIT_STATUS 0x89
+
+/// status
+#define MAC_FAILUE 0x01
+#define PHYSICAL_ERROR 0x04
+#define NETWORK_ACK_FAILUE 0x21
+#define NOT_ASSOCIATED 0x22
+#define NO_RESOURCES 0x32
+#define CONNECTIONS_FAILUE 0x76
+
+/// protocol
+#define PROTOCOL_UDP 0
+#define PROTOCOL_TCP 1
+
+/// option
+#define OPTION_LEAVEOPEN 1
+
+/// security
+#define SECURITY_OPEN 0
+#define SECURITY_WPA 1
+#define SECURITY_WPA2 2
+#define SECURITY_WEP40 3
+#define SECURITY_WEP104 4
+
+/// modem status
+#define JOINED_AP 0
+#define SSID_NOT_CONFIGURED 0x23
+#define JOINING_AP 0xff
+
+/// dns
+#define DNS_QUERY_A 1
+#define DNS_QUERY_NS 2
+#define DNS_QUERY_CNAME 5
+#define DNS_QUERY_PTR 12
+#define DNS_QUERY_MX 15
+#define DNS_QUERY_AAAA 28
+#define DNS_QUERY_ANY 255
+#define DNS_CLASS_IN 1
+
+struct DNSHeader {
+ uint16_t id;
+ uint16_t flags;
+ uint16_t questions;
+ uint16_t answers;
+ uint16_t authorities;
+ uint16_t additional;
+};
+
+struct DnsQuestionEnd {
+ uint16_t type;
+ uint16_t clas;
+};
+
+struct DnsAnswer {
+ uint16_t name;
+ uint16_t type;
+ uint16_t clas;
+ uint32_t ttl;
+ uint16_t length;
+} __attribute__((packed));
+
+
+#ifdef USE_WIFICLASS
+/**
+ * Primary interface for communicating with an XBee Wi-Fi.
+ */
+class XBeeWiFi : public XBee {
+public:
+ XBeeWiFi (PinName p_tx, PinName p_rx);
+
+ 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 setTimeout (int timeout);
+ int getStatus ();
+#ifdef USE_WIFIDNS
+ int getHostByName (const char* name, IpAddr &addr);
+#endif
+
+protected:
+ int getWiResponse (int apiId, int timeout = 1500);
+#ifdef USE_WIFIDNS
+ int createDnsRequest (const char* name, char *buf);
+ int getDnsResponse (const uint8_t *buf, int len, IpAddr &addr);
+#endif
+
+private:
+ IpAddr _nameserver;
+};
+#endif
+
+/**
+ * Represents a Wi-Fi TX packet that corresponds to Api Id: IPv4_TRANSMIT_REQUEST
+ */
+class IPv4TransmitRequest : public PayloadRequest {
+public:
+ /**
+ * Creates a unicast IPv4TransmitRequest with the DEFAULT_FRAME_ID
+ */
+ IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId);
+ IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint8_t dataLength);
+ /**
+ * Creates a default instance of this class. At a minimum you must specify
+ * a payload, payload length and a destination address before sending this request.
+ */
+ IPv4TransmitRequest();
+ IpAddr& getAddress();
+ uint16_t getDstPort();
+ uint16_t getSrcPort();
+ uint8_t getProtocol();
+ uint8_t getOption();
+ void setAddress(IpAddr& dstAddr);
+ void setDstPort(uint16_t dstPort);
+ void setSrcPort(uint16_t srcPort);
+ void setProtocol(uint8_t protocol);
+ void setOption(uint8_t option);
+protected:
+ // declare virtual functions
+ virtual uint8_t getFrameData(uint8_t pos);
+ virtual uint8_t getFrameDataLength();
+private:
+ IpAddr _dstAddr;
+ uint16_t _dstPort;
+ uint16_t _srcPort;
+ uint8_t _protocol;
+ uint8_t _option;
+};
+
+/**
+ * Represents a Wi-Fi TX status packet
+ */
+class Transmit_Status : public FrameIdResponse {
+public:
+ Transmit_Status();
+ uint8_t getStatus();
+ bool isSuccess();
+};
+
+/**
+ * Represents a Wi-Fi RX packet
+ */
+class IPV4RxFrame : public RxDataResponse {
+public:
+ IPV4RxFrame();
+ IpAddr& getSrcAddress();
+ uint16_t getDstPort();
+ uint16_t getSrcPort();
+ uint8_t getProtocol();
+ uint8_t getStatus();
+ virtual uint8_t getDataLength();
+ // frame position where data starts
+ virtual uint8_t getDataOffset();
+private:
+ IpAddr _srcAddr;
+};
+
+#endif //XBeeWiFi_h