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: XBee_WiFi_EA_LPC4088
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 DBG("**in getWiAddr after getResponse()**\r\n"); 00241 00242 DBG("**isOK: %d **\r\n", atResponse.isOk() ); 00243 DBG("**Response length: %d **\r\n", atResponse.getValueLength() ); 00244 DBG("**Response: %s **\r\n", atResponse.getValue() ); 00245 00246 if (atResponse.isOk() && atResponse.getValueLength() >= 7) { 00247 DBG("**Inside getWiAddr if**\r\n"); 00248 sscanf((char*)atResponse.getValue(), "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4); 00249 DBG("**ip(getWiAddr): %d.%d.%d.%d **\r\n", ip1,ip2,ip3,ip4); 00250 ipaddr = IpAddr(ip1, ip2, ip3, ip4); 00251 return 0; 00252 } 00253 return -1; 00254 } 00255 00256 int XBeeWiFi::setTimeout (int timeout) { 00257 // timeout 00258 uint8_t cmd[2] = {'T', 'P'}; 00259 char val[1]; 00260 AtCommandRequest atRequest; 00261 00262 val[0] = timeout; 00263 atRequest.setCommand(cmd); 00264 atRequest.setCommandValue((uint8_t*)val); 00265 atRequest.setCommandValueLength(1); 00266 atRequest.setFrameId(getNextFrameId()); 00267 send(atRequest); 00268 00269 return getWiResponse(AT_COMMAND_RESPONSE); 00270 } 00271 00272 int XBeeWiFi::getStatus () { 00273 // AI 00274 uint8_t cmd[2] = {'A', 'I'}; 00275 AtCommandRequest atRequest; 00276 00277 atRequest.setCommand(cmd); 00278 atRequest.setFrameId(getNextFrameId()); 00279 send(atRequest); 00280 00281 return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); 00282 } 00283 00284 int XBeeWiFi::getWiResponse (int apiId, int frameid, int timeout) { 00285 AtCommandResponse atResponse; 00286 00287 if (readPacket(timeout)) { 00288 if (frameid && frameid != getResponse().getFrameData()[0]) { 00289 DBG("Expected AT response but got %x (frame %d)\r\n", getResponse().getApiId(), getResponse().getFrameData()[0]); 00290 if (! readPacket(timeout)) return -1; 00291 DBG("Retry ok\r\n"); 00292 } 00293 00294 if (getResponse().getApiId() == apiId) { 00295 getResponse().getAtCommandResponse(atResponse); 00296 00297 if (getResponse().getApiId() == IPv4_RX_FRAME) { 00298 return 0; 00299 } else 00300 if (atResponse.isOk()) { 00301 00302 // if (getResponse().getFrameDataLength() > 4) { 00303 return atResponse.getValue()[0]; 00304 00305 } else { 00306 DBG("Command return error code: %x\r\n", atResponse.getStatus()); 00307 } 00308 } else { 00309 DBG("Expected AT response but got %x\r\n", getResponse().getApiId()); 00310 } 00311 } else { 00312 if (getResponse().isError()) { 00313 DBG("Error reading packet. Error code: %x\r\n", getResponse().getErrorCode()); 00314 } else { 00315 DBG("No response from radio\r\n"); 00316 } 00317 } 00318 00319 return -1; 00320 } 00321 00322 #ifdef USE_WIFIDNS 00323 int XBeeWiFi::setNameserver (IpAddr &nameserver, int port = DNS_PORT) { 00324 _nameserver = nameserver; 00325 _nameport = port; 00326 return 0; 00327 } 00328 00329 // *** Note: wifi is turned off when XBee send the port 53 udp packet. 00330 int XBeeWiFi::getHostByName (const char* name, IpAddr &addr) { 00331 Timer timeout; 00332 char buf[600]; 00333 int r, len; 00334 uint8_t cmd[2] = {'C', '0'}; 00335 char val[2]; 00336 IPv4TransmitRequest dnsRequest; 00337 AtCommandRequest atRequest; 00338 AtCommandResponse atResponse; 00339 00340 if (!strcmp(name, "localhost")) { 00341 addr = IpAddr(127, 0, 0, 1); 00342 return 0; 00343 } 00344 00345 // bind src port 00346 val[0] = (DNS_SRC_PORT >> 8) & 0xff; 00347 val[1] = DNS_SRC_PORT & 0xff; 00348 atRequest.setCommand(cmd); 00349 atRequest.setCommandValue((uint8_t*)val); 00350 atRequest.setCommandValueLength(2); 00351 atRequest.setFrameId(getNextFrameId()); 00352 send(atRequest); 00353 r = getWiResponse(AT_COMMAND_RESPONSE); 00354 DBG("wifi C0: %d\r\n", r); 00355 00356 // send DNS request 00357 len = createDnsRequest(name, buf); 00358 dnsRequest.setAddress(_nameserver); 00359 dnsRequest.setDstPort(_nameport); 00360 dnsRequest.setSrcPort(DNS_SRC_PORT); 00361 dnsRequest.setProtocol(PROTOCOL_UDP); 00362 dnsRequest.setPayload((uint8_t*)buf); 00363 dnsRequest.setPayloadLength(len); 00364 00365 // wait responce 00366 timeout.reset(); 00367 timeout.start(); 00368 while (timeout.read_ms() < DNS_TIMEOUT) { 00369 dnsRequest.setFrameId(getNextFrameId()); 00370 send(dnsRequest); 00371 00372 r = getWiResponse(TX_STATUS_RESPONSE, dnsRequest.getFrameId()); 00373 DBG("wifi TX: %d\r\n", r); 00374 00375 if (r >= 0) { 00376 // recv DNS request 00377 r = getWiResponse(IPv4_RX_FRAME, 0, 3000); 00378 DBG("wifi RX: %d\r\n", r); 00379 if (r >= 0) { 00380 timeout.stop(); 00381 getResponse().getAtCommandResponse(atResponse); 00382 return getDnsResponse(atResponse.getValue() + 6, atResponse.getValueLength() - 6, addr); 00383 } 00384 } else { 00385 break; 00386 } 00387 } 00388 timeout.stop(); 00389 00390 return -1; 00391 } 00392 00393 int XBeeWiFi::createDnsRequest (const char* name, char *buf) { 00394 struct DNSHeader *dnsHeader; 00395 struct DnsQuestionEnd *dnsEnd; 00396 int len, num; 00397 00398 // DNS header 00399 dnsHeader = (DNSHeader*)buf; 00400 dnsHeader->id = REVERSE_ENDIAN(0xdead); 00401 dnsHeader->flags = REVERSE_ENDIAN(0x100); 00402 dnsHeader->questions = REVERSE_ENDIAN(1); 00403 dnsHeader->answers = 0; 00404 dnsHeader->authorities = 0; 00405 dnsHeader->additional = 0; 00406 00407 // DNS question 00408 len = sizeof(DNSHeader); 00409 while ((num = (int)strchr(name, '.')) != NULL) { 00410 num = num - (int)name; 00411 buf[len] = num; 00412 len ++; 00413 strncpy(&buf[len], name, num); 00414 name = name + num + 1; 00415 len = len + num; 00416 } 00417 00418 if ((num = strlen(name)) != NULL) { 00419 buf[len] = num; 00420 len ++; 00421 strncpy(&buf[len], name, num); 00422 len = len + num; 00423 } 00424 buf[len] = 0; 00425 len ++; 00426 00427 dnsEnd = (DnsQuestionEnd*)&buf[len]; 00428 dnsEnd->type = REVERSE_ENDIAN(DNS_QUERY_A); 00429 dnsEnd->clas = REVERSE_ENDIAN(DNS_CLASS_IN); 00430 00431 return len + sizeof(DnsQuestionEnd); 00432 } 00433 00434 int XBeeWiFi::getDnsResponse (const uint8_t *buf, int len, IpAddr &addr) { 00435 int i; 00436 struct DNSHeader *dnsHeader; 00437 struct DnsAnswer *dnsAnswer; 00438 00439 // DNS header 00440 dnsHeader = (DNSHeader*)buf; 00441 if (REVERSE_ENDIAN(dnsHeader->id) != 0xdead || (REVERSE_ENDIAN(dnsHeader->flags) & 0x800f) != 0x8000) { 00442 return -1; 00443 } 00444 00445 // skip question 00446 for (i = sizeof(DNSHeader); buf[i] && i < len; i ++); 00447 i = i + 1 + sizeof(DnsQuestionEnd); 00448 00449 // DNS answer 00450 while (i < len) { 00451 dnsAnswer = (DnsAnswer*)&buf[i]; 00452 if (dnsAnswer->clas != REVERSE_ENDIAN(DNS_CLASS_IN)) { 00453 return -1; 00454 } 00455 00456 i = i + sizeof(DnsAnswer); 00457 if (dnsAnswer->type == REVERSE_ENDIAN(DNS_QUERY_A)) { 00458 addr = IpAddr(buf[i], buf[i + 1], buf[i + 2], buf[i + 3]); 00459 return 0; 00460 } 00461 i = i + dnsAnswer->length; 00462 } 00463 00464 return -1; 00465 } 00466 #endif 00467 00468 00469 IPv4TransmitRequest::IPv4TransmitRequest() : PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, NULL, 0) { 00470 } 00471 00472 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) { 00473 _dstAddr = dstAddr; 00474 _dstPort = dstPort; 00475 _srcPort = srcPort; 00476 _protocol = protocol; 00477 _option = option; 00478 } 00479 00480 IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint16_t dataLength): PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { 00481 _dstAddr = dstAddr; 00482 _dstPort = dstPort; 00483 _srcPort = 0x270f; 00484 _protocol = PROTOCOL_UDP; 00485 _option = 0; 00486 } 00487 00488 uint8_t IPv4TransmitRequest::getFrameData(uint16_t pos) { 00489 if (pos == 0) { 00490 return _dstAddr[0]; 00491 } else if (pos == 1) { 00492 return _dstAddr[1]; 00493 } else if (pos == 2) { 00494 return _dstAddr[2]; 00495 } else if (pos == 3) { 00496 return _dstAddr[3]; 00497 } else if (pos == 4) { 00498 return (_dstPort >> 8) & 0xff; 00499 } else if (pos == 5) { 00500 return _dstPort & 0xff; 00501 } else if (pos == 6) { 00502 return (_srcPort >> 8) & 0xff; 00503 } else if (pos == 7) { 00504 return _srcPort & 0xff; 00505 } else if (pos == 8) { 00506 return _protocol; 00507 } else if (pos == 9) { 00508 return _option; 00509 } else { 00510 return getPayload()[pos - IPv4_TRANSMIT_REQUEST_API_LENGTH]; 00511 } 00512 } 00513 00514 uint16_t IPv4TransmitRequest::getFrameDataLength() { 00515 return IPv4_TRANSMIT_REQUEST_API_LENGTH + getPayloadLength(); 00516 } 00517 00518 IpAddr& IPv4TransmitRequest::getAddress() { 00519 return _dstAddr; 00520 } 00521 00522 uint16_t IPv4TransmitRequest::getDstPort() { 00523 return _dstPort; 00524 } 00525 00526 uint16_t IPv4TransmitRequest::getSrcPort() { 00527 return _srcPort; 00528 } 00529 00530 uint8_t IPv4TransmitRequest::getProtocol() { 00531 return _protocol; 00532 } 00533 00534 uint8_t IPv4TransmitRequest::getOption() { 00535 return _option; 00536 } 00537 00538 void IPv4TransmitRequest::setAddress(IpAddr &dstAddr) { 00539 _dstAddr = dstAddr; 00540 } 00541 00542 void IPv4TransmitRequest::setDstPort(uint16_t dstPort) { 00543 _dstPort = dstPort; 00544 } 00545 00546 void IPv4TransmitRequest::setSrcPort(uint16_t srcPort) { 00547 _srcPort = srcPort; 00548 } 00549 00550 void IPv4TransmitRequest::setProtocol(uint8_t protocol) { 00551 _protocol = protocol; 00552 } 00553 00554 void IPv4TransmitRequest::setOption(uint8_t option) { 00555 _option = option; 00556 } 00557 00558 00559 Transmit_Status::Transmit_Status() : FrameIdResponse() { 00560 00561 } 00562 00563 uint8_t Transmit_Status::getStatus() { 00564 return getFrameData()[1]; 00565 } 00566 00567 bool Transmit_Status::isSuccess() { 00568 return getStatus() == SUCCESS; 00569 } 00570 00571 00572 IPV4RxFrame::IPV4RxFrame () { 00573 } 00574 00575 IpAddr& IPV4RxFrame::getSrcAddress() { 00576 _srcAddr = IpAddr(getFrameData()[0], getFrameData()[1], getFrameData()[2], getFrameData()[3]); 00577 return _srcAddr; 00578 } 00579 00580 uint16_t IPV4RxFrame::getDstPort() { 00581 return (getFrameData()[4] << 8) + getFrameData()[5]; 00582 } 00583 00584 uint16_t IPV4RxFrame::getSrcPort() { 00585 return (getFrameData()[6] << 8) + getFrameData()[7]; 00586 } 00587 00588 uint8_t IPV4RxFrame::getProtocol() { 00589 return getFrameData()[8]; 00590 } 00591 00592 uint8_t IPV4RxFrame::getStatus() { 00593 return getFrameData()[9]; 00594 } 00595 00596 // markers to read data from packet array. this is the index, so the 12th item in the array 00597 uint8_t IPV4RxFrame::getDataOffset() { 00598 return 10; 00599 } 00600 00601 uint16_t IPV4RxFrame::getDataLength() { 00602 return getPacketLength() - getDataOffset() - 1; 00603 } 00604 00605 #endif 00606
Generated on Sat Jul 16 2022 20:27:13 by
1.7.2
