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: XBeeWiFi_SPI_example
Fork of XBee by
XBeeWiFi.cpp
00001 /** 00002 * XBee Wi-Fi library for mbed 00003 * Copyright (c) 2011 Hiroshi Suga 00004 * Released under the MIT License: http://mbed.org/license/mit 00005 */ 00006 00007 /** @file 00008 * @brief XBee Wi-Fi library for mbed 00009 */ 00010 00011 #include "XBee_conf.h" 00012 #ifdef ENABLE_XBEE_WIFI 00013 00014 //#define DEBUG 00015 #include "dbg.h" 00016 00017 #include "mbed.h" 00018 #include "XBee.h" 00019 #include "XBeeWiFi.h" 00020 #include "EthernetNetIf.h" 00021 00022 #define REVERSE_ENDIAN(x) (uint16_t)(((uint16_t)x >> 8) | ((uint16_t)x << 8)) 00023 00024 #ifndef USE_XBEE_SPI 00025 XBeeWiFi::XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts) : XBee(p_tx, p_rx, p_cts, p_rts) { 00026 } 00027 #endif 00028 00029 #ifdef USE_XBEE_SPI 00030 XBeeWiFi::XBeeWiFi (PinName p_mosi, PinName p_miso, PinName p_sclk, PinName p_ssel, PinName p_attn, PinName p_reset) : 00031 XBee(p_mosi, p_miso, p_sclk, p_ssel, p_attn, p_reset) { 00032 } 00033 #endif 00034 00035 int XBeeWiFi::setup (int security, const char *ssid, const char *pin) { 00036 int len, r; 00037 uint8_t cmd[2], val[32]; 00038 AtCommandRequest atRequest; 00039 00040 // SSID 00041 memcpy(cmd, "ID", 2); 00042 len = strlen(ssid); 00043 memcpy(val, ssid, len); 00044 atRequest.setCommand(cmd); 00045 atRequest.setCommandValue(val); 00046 atRequest.setCommandValueLength(len); 00047 atRequest.setFrameId(getNextFrameId()); 00048 send(atRequest); 00049 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00050 DBG("wifi ID: %d\r\n", r); 00051 if (r < 0) return -1; 00052 00053 if (security != SECURITY_OPEN) { 00054 // PIN 00055 memcpy(cmd, "PK", 2); 00056 len = strlen(pin); 00057 memcpy(val, pin, len); 00058 atRequest.setCommand(cmd); 00059 atRequest.setCommandValue(val); 00060 atRequest.setCommandValueLength(len); 00061 atRequest.setFrameId(getNextFrameId()); 00062 send(atRequest); 00063 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00064 DBG("wifi PK: %d\r\n", r); 00065 if (r < 0) return -1; 00066 } 00067 00068 // security type 00069 memcpy(cmd, "EE", 2); 00070 val[0] = security; 00071 atRequest.setCommand(cmd); 00072 atRequest.setCommandValue(val); 00073 atRequest.setCommandValueLength(1); 00074 atRequest.setFrameId(getNextFrameId()); 00075 send(atRequest); 00076 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00077 DBG("wifi EE: %d\r\n", r); 00078 if (r < 0) return -1; 00079 00080 return 0; 00081 } 00082 00083 int XBeeWiFi::setup (const char *ssid) { 00084 return setup(SECURITY_OPEN, ssid, NULL); 00085 } 00086 00087 int XBeeWiFi::reset () { 00088 // RESET 00089 uint8_t cmd[2] = {'N', 'R'}; // Network reset 00090 // uint8_t cmd[2] = {'F', 'R'}; // Software reset 00091 AtCommandRequest atRequest; 00092 00093 atRequest.setCommand(cmd); 00094 atRequest.setFrameId(getNextFrameId()); 00095 send(atRequest); 00096 return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00097 } 00098 00099 int XBeeWiFi::baud (int b) { 00100 // RESET 00101 uint8_t cmd[2] = {'B', 'D'}; 00102 char val[4]; 00103 AtCommandRequest atRequest; 00104 int r, len; 00105 00106 if (b < 0x100) { 00107 val[0] = b; 00108 len = 1; 00109 } else { 00110 val[0] = (b >> 24) & 0xff; 00111 val[1] = (b >> 16) & 0xff; 00112 val[2] = (b >> 8) & 0xff; 00113 val[3] = b & 0xff; 00114 len = 4; 00115 } 00116 atRequest.setCommand(cmd); 00117 atRequest.setCommandValue((uint8_t*)val); 00118 atRequest.setCommandValueLength(len); 00119 atRequest.setFrameId(getNextFrameId()); 00120 send(atRequest); 00121 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00122 00123 #ifndef USE_XBEE_SPI 00124 if (r == 0) { 00125 begin(b); 00126 } 00127 #endif 00128 return r; 00129 } 00130 00131 int XBeeWiFi::setAddress () { 00132 // DHCP 00133 uint8_t cmd[2] = {'M', 'A'}; 00134 char val[1] = {0}; 00135 AtCommandRequest atRequest; 00136 00137 _nameserver = IpAddr(0,0,0,0); 00138 _nameport = DNS_PORT; 00139 00140 atRequest.setCommand(cmd); 00141 atRequest.setCommandValue((uint8_t*)val); 00142 atRequest.setCommandValueLength(1); 00143 atRequest.setFrameId(getNextFrameId()); 00144 send(atRequest); 00145 00146 return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00147 } 00148 00149 int XBeeWiFi::setAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) { 00150 uint8_t cmd[2]; 00151 char val[32]; 00152 AtCommandRequest atRequest; 00153 00154 // Static 00155 memcpy(cmd, "MA", 2); 00156 val[0] = 1; 00157 atRequest.setCommand(cmd); 00158 atRequest.setCommandValue((uint8_t*)val); 00159 atRequest.setCommandValueLength(1); 00160 atRequest.setFrameId(getNextFrameId()); 00161 send(atRequest); 00162 getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00163 00164 // IP address 00165 memcpy(cmd, "MY", 2); 00166 sprintf(val, "%d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); 00167 atRequest.setCommand(cmd); 00168 atRequest.setCommandValue((uint8_t*)val); 00169 atRequest.setCommandValueLength(strlen(val)); 00170 atRequest.setFrameId(getNextFrameId()); 00171 send(atRequest); 00172 getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00173 00174 // sub netmask 00175 memcpy(cmd, "NK", 2); 00176 sprintf(val, "%d.%d.%d.%d", netmask[0], netmask[1], netmask[2], netmask[3]); 00177 atRequest.setCommand(cmd); 00178 atRequest.setCommandValue((uint8_t*)val); 00179 atRequest.setCommandValueLength(strlen(val)); 00180 atRequest.setFrameId(getNextFrameId()); 00181 send(atRequest); 00182 getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00183 00184 // default gateway 00185 memcpy(cmd, "GW", 2); 00186 sprintf(val, "%d.%d.%d.%d", gateway[0], gateway[1], gateway[2], gateway[3]); 00187 atRequest.setCommand(cmd); 00188 atRequest.setCommandValue((uint8_t*)val); 00189 atRequest.setCommandValueLength(strlen(val)); 00190 atRequest.setFrameId(getNextFrameId()); 00191 send(atRequest); 00192 getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00193 00194 // name server 00195 _nameserver = nameserver; 00196 _nameport = DNS_PORT; 00197 00198 return 0; 00199 } 00200 00201 int XBeeWiFi::getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) { 00202 int r; 00203 uint8_t cmd[2]; 00204 AtCommandRequest atRequest; 00205 AtCommandResponse atResponse; 00206 00207 memcpy(cmd, "MY", 2); 00208 atRequest.setCommand(cmd); 00209 atRequest.clearCommandValue(); 00210 atRequest.setFrameId(getNextFrameId()); 00211 send(atRequest); 00212 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00213 DBG("wifi MY: %d\r\n", r); 00214 if (r >= 0) { 00215 r = getWiAddr(ipaddr); 00216 } 00217 00218 memcpy(cmd, "MK", 2); 00219 atRequest.setCommand(cmd); 00220 atRequest.clearCommandValue(); 00221 atRequest.setFrameId(getNextFrameId()); 00222 send(atRequest); 00223 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00224 DBG("wifi MK: %d\r\n", r); 00225 if (r >= 0) { 00226 r = getWiAddr(netmask); 00227 } 00228 00229 memcpy(cmd, "GW", 2); 00230 atRequest.setCommand(cmd); 00231 atRequest.clearCommandValue(); 00232 atRequest.setFrameId(getNextFrameId()); 00233 send(atRequest); 00234 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00235 DBG("wifi GW: %d\r\n", r); 00236 if (r >= 0) { 00237 r = getWiAddr(gateway); 00238 } 00239 00240 nameserver = _nameserver; 00241 00242 return 0; 00243 } 00244 00245 int XBeeWiFi::getWiAddr (IpAddr &ipaddr) { 00246 int ip1, ip2, ip3, ip4; 00247 AtCommandResponse atResponse; 00248 00249 getResponse().getAtCommandResponse(atResponse); 00250 if (atResponse.isOk() && atResponse.getValueLength() >= 7) { 00251 sscanf((char*)atResponse.getValue(), "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4); 00252 ipaddr = IpAddr(ip1, ip2, ip3, ip4); 00253 return 0; 00254 } 00255 return -1; 00256 } 00257 00258 int XBeeWiFi::setTimeout (int timeout) { 00259 // timeout 00260 uint8_t cmd[2] = {'T', 'P'}; 00261 char val[1]; 00262 AtCommandRequest atRequest; 00263 00264 val[0] = timeout; 00265 atRequest.setCommand(cmd); 00266 atRequest.setCommandValue((uint8_t*)val); 00267 atRequest.setCommandValueLength(1); 00268 atRequest.setFrameId(getNextFrameId()); 00269 send(atRequest); 00270 00271 return getWiResponse(AT_COMMAND_RESPONSE); 00272 } 00273 00274 int XBeeWiFi::getStatus () { 00275 // AI 00276 uint8_t cmd[2] = {'A', 'I'}; 00277 AtCommandRequest atRequest; 00278 00279 atRequest.setCommand(cmd); 00280 atRequest.setFrameId(getNextFrameId()); 00281 send(atRequest); 00282 00283 return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00284 } 00285 00286 int XBeeWiFi::getWiResponse (int apiId, int frameid, int timeout) { 00287 AtCommandResponse atResponse; 00288 00289 if (readPacket(timeout)) { 00290 if (frameid && frameid != getResponse().getFrameData()[0]) { 00291 DBG("Expected AT response but got %x (frame %d)\r\n", getResponse().getApiId(), getResponse().getFrameData()[0]); 00292 if (! readPacket(timeout)) return -1; 00293 DBG("Retry ok\r\n"); 00294 } 00295 00296 if (getResponse().getApiId() == apiId) { 00297 getResponse().getAtCommandResponse(atResponse); 00298 00299 if (getResponse().getApiId() == IPv4_RX_FRAME) { 00300 return 0; 00301 } else 00302 if (atResponse.isOk()) { 00303 00304 // if (getResponse().getFrameDataLength() > 4) { 00305 return atResponse.getValue()[0]; 00306 00307 } else { 00308 DBG("Command return error code: %x\r\n", atResponse.getStatus()); 00309 } 00310 } else { 00311 DBG("Expected AT response but got %x\r\n", getResponse().getApiId()); 00312 } 00313 } else { 00314 if (getResponse().isError()) { 00315 DBG("Error reading packet. Error code: %x\r\n", getResponse().getErrorCode()); 00316 } else { 00317 DBG("No response from radio\r\n"); 00318 } 00319 } 00320 00321 return -1; 00322 } 00323 00324 #ifdef USE_WIFIDNS 00325 int XBeeWiFi::setNameserver (IpAddr &nameserver, int port) { 00326 _nameserver = nameserver; 00327 _nameport = port; 00328 return 0; 00329 } 00330 00331 // *** Note: wifi is turned off when XBee send the port 53 udp packet. 00332 int XBeeWiFi::getHostByName (const char* name, IpAddr &addr) { 00333 Timer timeout; 00334 char buf[600]; 00335 int r, len; 00336 uint8_t cmd[2] = {'C', '0'}; 00337 char val[2]; 00338 IPv4TransmitRequest dnsRequest; 00339 AtCommandRequest atRequest; 00340 AtCommandResponse atResponse; 00341 00342 if (!strcmp(name, "localhost")) { 00343 addr = IpAddr(127, 0, 0, 1); 00344 return 0; 00345 } 00346 00347 // bind src port 00348 val[0] = (DNS_SRC_PORT >> 8) & 0xff; 00349 val[1] = DNS_SRC_PORT & 0xff; 00350 atRequest.setCommand(cmd); 00351 atRequest.setCommandValue((uint8_t*)val); 00352 atRequest.setCommandValueLength(2); 00353 atRequest.setFrameId(getNextFrameId()); 00354 send(atRequest); 00355 r = getWiResponse(AT_COMMAND_RESPONSE); 00356 DBG("wifi C0: %d\r\n", r); 00357 00358 // send DNS request 00359 len = createDnsRequest(name, buf); 00360 dnsRequest.setAddress(_nameserver); 00361 dnsRequest.setDstPort(_nameport); 00362 dnsRequest.setSrcPort(DNS_SRC_PORT); 00363 dnsRequest.setProtocol(PROTOCOL_UDP); 00364 dnsRequest.setPayload((uint8_t*)buf); 00365 dnsRequest.setPayloadLength(len); 00366 00367 // wait responce 00368 timeout.reset(); 00369 timeout.start(); 00370 while (timeout.read_ms() < DNS_TIMEOUT) { 00371 dnsRequest.setFrameId(getNextFrameId()); 00372 send(dnsRequest); 00373 00374 r = getWiResponse(TX_STATUS_RESPONSE, dnsRequest.getFrameId()); 00375 DBG("wifi TX: %d\r\n", r); 00376 00377 if (r >= 0) { 00378 // recv DNS request 00379 r = getWiResponse(IPv4_RX_FRAME, 0, 3000); 00380 DBG("wifi RX: %d\r\n", r); 00381 if (r >= 0) { 00382 timeout.stop(); 00383 getResponse().getAtCommandResponse(atResponse); 00384 return getDnsResponse(atResponse.getValue() + 6, atResponse.getValueLength() - 6, addr); 00385 } 00386 } else { 00387 break; 00388 } 00389 } 00390 timeout.stop(); 00391 00392 return -1; 00393 } 00394 00395 int XBeeWiFi::createDnsRequest (const char* name, char *buf) { 00396 struct DNSHeader *dnsHeader; 00397 struct DnsQuestionEnd *dnsEnd; 00398 int len, num; 00399 00400 // DNS header 00401 dnsHeader = (DNSHeader*)buf; 00402 dnsHeader->id = REVERSE_ENDIAN(0xdead); 00403 dnsHeader->flags = REVERSE_ENDIAN(0x100); 00404 dnsHeader->questions = REVERSE_ENDIAN(1); 00405 dnsHeader->answers = 0; 00406 dnsHeader->authorities = 0; 00407 dnsHeader->additional = 0; 00408 00409 // DNS question 00410 len = sizeof(DNSHeader); 00411 while ((num = (int)strchr(name, '.')) != NULL) { 00412 num = num - (int)name; 00413 buf[len] = num; 00414 len ++; 00415 strncpy(&buf[len], name, num); 00416 name = name + num + 1; 00417 len = len + num; 00418 } 00419 00420 if ((num = strlen(name)) != NULL) { 00421 buf[len] = num; 00422 len ++; 00423 strncpy(&buf[len], name, num); 00424 len = len + num; 00425 } 00426 buf[len] = 0; 00427 len ++; 00428 00429 dnsEnd = (DnsQuestionEnd*)&buf[len]; 00430 dnsEnd->type = REVERSE_ENDIAN(DNS_QUERY_A); 00431 dnsEnd->clas = REVERSE_ENDIAN(DNS_CLASS_IN); 00432 00433 return len + sizeof(DnsQuestionEnd); 00434 } 00435 00436 int XBeeWiFi::getDnsResponse (const uint8_t *buf, int len, IpAddr &addr) { 00437 int i; 00438 struct DNSHeader *dnsHeader; 00439 struct DnsAnswer *dnsAnswer; 00440 00441 // DNS header 00442 dnsHeader = (DNSHeader*)buf; 00443 if (REVERSE_ENDIAN(dnsHeader->id) != 0xdead || (REVERSE_ENDIAN(dnsHeader->flags) & 0x800f) != 0x8000) { 00444 return -1; 00445 } 00446 00447 // skip question 00448 for (i = sizeof(DNSHeader); buf[i] && i < len; i ++); 00449 i = i + 1 + sizeof(DnsQuestionEnd); 00450 00451 // DNS answer 00452 while (i < len) { 00453 dnsAnswer = (DnsAnswer*)&buf[i]; 00454 if (dnsAnswer->clas != REVERSE_ENDIAN(DNS_CLASS_IN)) { 00455 return -1; 00456 } 00457 00458 i = i + sizeof(DnsAnswer); 00459 if (dnsAnswer->type == REVERSE_ENDIAN(DNS_QUERY_A)) { 00460 addr = IpAddr(buf[i], buf[i + 1], buf[i + 2], buf[i + 3]); 00461 return 0; 00462 } 00463 i = i + dnsAnswer->length; 00464 } 00465 00466 return -1; 00467 } 00468 #endif 00469 00470 00471 IPv4TransmitRequest::IPv4TransmitRequest() : PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, NULL, 0) { 00472 } 00473 00474 IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId): PayloadRequest(IPv4_TRANSMIT_REQUEST, frameId, data, dataLength) { 00475 _dstAddr = dstAddr; 00476 _dstPort = dstPort; 00477 _srcPort = srcPort; 00478 _protocol = protocol; 00479 _option = option; 00480 } 00481 00482 IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint16_t dataLength): PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { 00483 _dstAddr = dstAddr; 00484 _dstPort = dstPort; 00485 _srcPort = 0x270f; 00486 _protocol = PROTOCOL_UDP; 00487 _option = 0; 00488 } 00489 00490 uint8_t IPv4TransmitRequest::getFrameData(uint16_t pos) { 00491 if (pos == 0) { 00492 return _dstAddr[0]; 00493 } else if (pos == 1) { 00494 return _dstAddr[1]; 00495 } else if (pos == 2) { 00496 return _dstAddr[2]; 00497 } else if (pos == 3) { 00498 return _dstAddr[3]; 00499 } else if (pos == 4) { 00500 return (_dstPort >> 8) & 0xff; 00501 } else if (pos == 5) { 00502 return _dstPort & 0xff; 00503 } else if (pos == 6) { 00504 return (_srcPort >> 8) & 0xff; 00505 } else if (pos == 7) { 00506 return _srcPort & 0xff; 00507 } else if (pos == 8) { 00508 return _protocol; 00509 } else if (pos == 9) { 00510 return _option; 00511 } else { 00512 return getPayload()[pos - IPv4_TRANSMIT_REQUEST_API_LENGTH]; 00513 } 00514 } 00515 00516 uint16_t IPv4TransmitRequest::getFrameDataLength() { 00517 return IPv4_TRANSMIT_REQUEST_API_LENGTH + getPayloadLength(); 00518 } 00519 00520 IpAddr& IPv4TransmitRequest::getAddress() { 00521 return _dstAddr; 00522 } 00523 00524 uint16_t IPv4TransmitRequest::getDstPort() { 00525 return _dstPort; 00526 } 00527 00528 uint16_t IPv4TransmitRequest::getSrcPort() { 00529 return _srcPort; 00530 } 00531 00532 uint8_t IPv4TransmitRequest::getProtocol() { 00533 return _protocol; 00534 } 00535 00536 uint8_t IPv4TransmitRequest::getOption() { 00537 return _option; 00538 } 00539 00540 void IPv4TransmitRequest::setAddress(IpAddr &dstAddr) { 00541 _dstAddr = dstAddr; 00542 } 00543 00544 void IPv4TransmitRequest::setDstPort(uint16_t dstPort) { 00545 _dstPort = dstPort; 00546 } 00547 00548 void IPv4TransmitRequest::setSrcPort(uint16_t srcPort) { 00549 _srcPort = srcPort; 00550 } 00551 00552 void IPv4TransmitRequest::setProtocol(uint8_t protocol) { 00553 _protocol = protocol; 00554 } 00555 00556 void IPv4TransmitRequest::setOption(uint8_t option) { 00557 _option = option; 00558 } 00559 00560 00561 Transmit_Status::Transmit_Status() : FrameIdResponse() { 00562 00563 } 00564 00565 uint8_t Transmit_Status::getStatus() { 00566 return getFrameData()[1]; 00567 } 00568 00569 bool Transmit_Status::isSuccess() { 00570 return getStatus() == SUCCESS; 00571 } 00572 00573 00574 IPV4RxFrame::IPV4RxFrame () { 00575 } 00576 00577 IpAddr& IPV4RxFrame::getSrcAddress() { 00578 _srcAddr = IpAddr(getFrameData()[0], getFrameData()[1], getFrameData()[2], getFrameData()[3]); 00579 return _srcAddr; 00580 } 00581 00582 uint16_t IPV4RxFrame::getDstPort() { 00583 return (getFrameData()[4] << 8) + getFrameData()[5]; 00584 } 00585 00586 uint16_t IPV4RxFrame::getSrcPort() { 00587 return (getFrameData()[6] << 8) + getFrameData()[7]; 00588 } 00589 00590 uint8_t IPV4RxFrame::getProtocol() { 00591 return getFrameData()[8]; 00592 } 00593 00594 uint8_t IPV4RxFrame::getStatus() { 00595 return getFrameData()[9]; 00596 } 00597 00598 // markers to read data from packet array. this is the index, so the 12th item in the array 00599 uint8_t IPV4RxFrame::getDataOffset() { 00600 return 10; 00601 } 00602 00603 uint16_t IPV4RxFrame::getDataLength() { 00604 return getPacketLength() - getDataOffset() - 1; 00605 } 00606 00607 #endif 00608
Generated on Tue Jul 12 2022 23:53:35 by
1.7.2
