no changes
Fork of XBee by
XBeeWiFi.cpp
- Committer:
- okini3939
- Date:
- 2011-07-29
- Revision:
- 2:6efb3541af61
- Child:
- 3:8573b122fa84
File content as of revision 2:6efb3541af61:
/** * 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; }