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