http
Embed:
(wiki syntax)
Show/hide line numbers
ESP8266.cpp
00001 /* ESP8266 Example 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "ESP8266.h" 00018 00019 ESP8266::ESP8266(PinName tx, PinName rx, bool debug) 00020 : _serial(tx, rx, 1024), _parser(_serial) 00021 , _packets(0), _packets_end(&_packets) 00022 { 00023 _serial.baud(115200); 00024 _parser.debugOn(debug); 00025 } 00026 00027 int ESP8266::get_firmware_version() 00028 { 00029 _parser.send("AT+GMR"); 00030 int version; 00031 if(_parser.recv("SDK version:%d", &version) && _parser.recv("OK")) { 00032 return version; 00033 } else { 00034 // Older firmware versions do not prefix the version with "SDK version: " 00035 return -1; 00036 } 00037 00038 } 00039 00040 bool ESP8266::startup(int mode) 00041 { 00042 //only 3 valid modes 00043 if(mode < 1 || mode > 3) { 00044 return false; 00045 } 00046 00047 bool success = _parser.send("AT+CWMODE_CUR=%d", mode) 00048 && _parser.recv("OK") 00049 && _parser.send("AT+CIPMUX=1") 00050 && _parser.recv("OK"); 00051 00052 _parser.oob("+IPD", this, &ESP8266::_packet_handler); 00053 00054 return success; 00055 } 00056 00057 bool ESP8266::reset(void) 00058 { 00059 for (int i = 0; i < 2; i++) { 00060 if (_parser.send("AT+RST") 00061 && _parser.recv("OK\r\nready")) { 00062 return true; 00063 } 00064 } 00065 00066 return false; 00067 } 00068 00069 bool ESP8266::dhcp(bool enabled, int mode) 00070 { 00071 //only 3 valid modes 00072 if(mode < 0 || mode > 2) { 00073 return false; 00074 } 00075 00076 return _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode) 00077 && _parser.recv("OK"); 00078 } 00079 00080 bool ESP8266::connect(const char *ap, const char *passPhrase) 00081 { 00082 return _parser.send("AT+CWJAP=\"%s\",\"%s\"", ap, passPhrase) 00083 && _parser.recv("OK"); 00084 } 00085 00086 bool ESP8266::disconnect(void) 00087 { 00088 return _parser.send("AT+CWQAP") && _parser.recv("OK"); 00089 } 00090 00091 const char *ESP8266::getIPAddress(void) 00092 { 00093 if (!(_parser.send("AT+CIFSR") 00094 && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer) 00095 && _parser.recv("OK"))) { 00096 return 0; 00097 } 00098 00099 return _ip_buffer; 00100 } 00101 00102 const char *ESP8266::getMACAddress(void) 00103 { 00104 if (!(_parser.send("AT+CIFSR") 00105 && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer) 00106 && _parser.recv("OK"))) { 00107 return 0; 00108 } 00109 00110 return _mac_buffer; 00111 } 00112 00113 const char *ESP8266::getGateway() 00114 { 00115 if (!(_parser.send("AT+CIPSTA?") 00116 && _parser.recv("+CIPSTA:gateway:\"%15[^\"]\"", _gateway_buffer) 00117 && _parser.recv("OK"))) { 00118 return 0; 00119 } 00120 00121 return _gateway_buffer; 00122 } 00123 00124 const char *ESP8266::getNetmask() 00125 { 00126 if (!(_parser.send("AT+CIPSTA?") 00127 && _parser.recv("+CIPSTA:netmask:\"%15[^\"]\"", _netmask_buffer) 00128 && _parser.recv("OK"))) { 00129 return 0; 00130 } 00131 00132 return _netmask_buffer; 00133 } 00134 00135 int8_t ESP8266::getRSSI() 00136 { 00137 int8_t rssi; 00138 char bssid[18]; 00139 00140 if (!(_parser.send("AT+CWJAP?") 00141 && _parser.recv("+CWJAP:\"%*[^\"]\",\"%17[^\"]\"", bssid) 00142 && _parser.recv("OK"))) { 00143 return 0; 00144 } 00145 00146 if (!(_parser.send("AT+CWLAP=\"\",\"%s\",", bssid) 00147 && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi) 00148 && _parser.recv("OK"))) { 00149 return 0; 00150 } 00151 00152 return rssi; 00153 } 00154 00155 bool ESP8266::isConnected(void) 00156 { 00157 return getIPAddress() != 0; 00158 } 00159 00160 int ESP8266::scan(WiFiAccessPoint *res, unsigned limit) 00161 { 00162 unsigned cnt = 0; 00163 nsapi_wifi_ap_t ap; 00164 00165 if (!_parser.send("AT+CWLAP")) { 00166 return NSAPI_ERROR_DEVICE_ERROR; 00167 } 00168 00169 while (recv_ap(&ap)) { 00170 if (cnt < limit) { 00171 res[cnt] = WiFiAccessPoint(ap); 00172 } 00173 00174 cnt++; 00175 if (limit != 0 && cnt >= limit) { 00176 break; 00177 } 00178 } 00179 00180 return cnt; 00181 } 00182 00183 bool ESP8266::open(const char *type, int id, const char* addr, int port) 00184 { 00185 //IDs only 0-4 00186 if(id > 4) { 00187 return false; 00188 } 00189 return _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port) 00190 && _parser.recv("OK"); 00191 } 00192 00193 bool ESP8266::dns_lookup(const char* name, char* ip) 00194 { 00195 return _parser.send("AT+CIPDOMAIN=\"%s\"", name) && _parser.recv("+CIPDOMAIN:%s%*[\r]%*[\n]", ip); 00196 } 00197 00198 bool ESP8266::send(int id, const void *data, uint32_t amount) 00199 { 00200 //May take a second try if device is busy 00201 for (unsigned i = 0; i < 2; i++) { 00202 if (_parser.send("AT+CIPSEND=%d,%d", id, amount) 00203 && _parser.recv(">") 00204 && _parser.write((char*)data, (int)amount) >= 0) { 00205 return true; 00206 } 00207 } 00208 00209 return false; 00210 } 00211 00212 void ESP8266::_packet_handler() 00213 { 00214 int id; 00215 uint32_t amount; 00216 00217 // parse out the packet 00218 if (!_parser.recv(",%d,%d:", &id, &amount)) { 00219 return; 00220 } 00221 00222 struct packet *packet = (struct packet*)malloc( 00223 sizeof(struct packet) + amount); 00224 if (!packet) { 00225 return; 00226 } 00227 00228 packet->id = id; 00229 packet->len = amount; 00230 packet->next = 0; 00231 00232 if (!(_parser.read((char*)(packet + 1), amount))) { 00233 free(packet); 00234 return; 00235 } 00236 00237 // append to packet list 00238 *_packets_end = packet; 00239 _packets_end = &packet->next; 00240 } 00241 00242 int32_t ESP8266::recv(int id, void *data, uint32_t amount) 00243 { 00244 while (true) { 00245 // check if any packets are ready for us 00246 for (struct packet **p = &_packets; *p; p = &(*p)->next) { 00247 if ((*p)->id == id) { 00248 struct packet *q = *p; 00249 00250 if (q->len <= amount) { // Return and remove full packet 00251 memcpy(data, q+1, q->len); 00252 00253 if (_packets_end == &(*p)->next) { 00254 _packets_end = p; 00255 } 00256 *p = (*p)->next; 00257 00258 uint32_t len = q->len; 00259 free(q); 00260 return len; 00261 } else { // return only partial packet 00262 memcpy(data, q+1, amount); 00263 00264 q->len -= amount; 00265 memmove(q+1, (uint8_t*)(q+1) + amount, q->len); 00266 00267 return amount; 00268 } 00269 } 00270 } 00271 00272 // Wait for inbound packet 00273 if (!_parser.recv("OK")) { 00274 return -1; 00275 } 00276 } 00277 } 00278 00279 bool ESP8266::close(int id) 00280 { 00281 //May take a second try if device is busy 00282 for (unsigned i = 0; i < 2; i++) { 00283 if (_parser.send("AT+CIPCLOSE=%d", id) 00284 && _parser.recv("OK")) { 00285 return true; 00286 } 00287 } 00288 00289 return false; 00290 } 00291 00292 void ESP8266::setTimeout(uint32_t timeout_ms) 00293 { 00294 _parser.setTimeout(timeout_ms); 00295 } 00296 00297 bool ESP8266::readable() 00298 { 00299 return _serial.readable(); 00300 } 00301 00302 bool ESP8266::writeable() 00303 { 00304 return _serial.writeable(); 00305 } 00306 00307 void ESP8266::attach(Callback<void()> func) 00308 { 00309 _serial.attach(func); 00310 } 00311 00312 bool ESP8266::recv_ap(nsapi_wifi_ap_t *ap) 00313 { 00314 int sec; 00315 bool ret = _parser.recv("+CWLAP:(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%d", &sec, ap->ssid, 00316 &ap->rssi, &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4], 00317 &ap->bssid[5], &ap->channel); 00318 00319 ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN; 00320 00321 return ret; 00322 }
Generated on Wed Jul 13 2022 01:16:06 by
1.7.2