XBee-mbed library http://mbed.org/users/okini3939/notebook/xbee-mbed/
Dependents: device_server_udp led_sender_post XBee_API_ex1 XBee_API_ex2 ... more
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 Tue Jul 12 2022 18:07:39 by 1.7.2