version 1.6
Dependents: iot_water_monitor_v2
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 #define ESP8266_DEFAULT_BAUD_RATE 115200 00020 00021 ESP8266::ESP8266(PinName tx, PinName rx, bool debug) 00022 : _serial(tx, rx, ESP8266_DEFAULT_BAUD_RATE), 00023 _parser(&_serial), 00024 _packets(0), 00025 _packets_end(&_packets) 00026 { 00027 _serial.set_baud( ESP8266_DEFAULT_BAUD_RATE ); 00028 _parser.debug_on(debug); 00029 _parser.set_delimiter("\r\n"); 00030 } 00031 00032 int ESP8266::get_firmware_version() 00033 { 00034 _parser.send("AT+GMR"); 00035 int version; 00036 if(_parser.recv("SDK version:%d", &version) && _parser.recv("OK")) { 00037 return version; 00038 } else { 00039 // Older firmware versions do not prefix the version with "SDK version: " 00040 return -1; 00041 } 00042 00043 } 00044 00045 bool ESP8266::startup(int mode) 00046 { 00047 //only 3 valid modes 00048 if(mode < 1 || mode > 3) { 00049 return false; 00050 } 00051 00052 bool success = _parser.send("AT+CWMODE_CUR=%d", mode) 00053 && _parser.recv("OK") 00054 && _parser.send("AT+CIPMUX=1") 00055 && _parser.recv("OK"); 00056 00057 _parser.oob("+IPD", callback(this, &ESP8266::_packet_handler)); 00058 00059 return success; 00060 } 00061 00062 bool ESP8266::reset(void) 00063 { 00064 for (int i = 0; i < 2; i++) { 00065 if (_parser.send("AT+RST") 00066 && _parser.recv("OK\r\nready")) { 00067 return true; 00068 } 00069 } 00070 00071 return false; 00072 } 00073 00074 bool ESP8266::dhcp(bool enabled, int mode) 00075 { 00076 //only 3 valid modes 00077 if(mode < 0 || mode > 2) { 00078 return false; 00079 } 00080 00081 return _parser.send("AT+CWDHCP_CUR=%d,%d", enabled?1:0, mode) 00082 && _parser.recv("OK"); 00083 } 00084 00085 bool ESP8266::connect(const char *ap, const char *passPhrase) 00086 { 00087 return _parser.send("AT+CWJAP_CUR=\"%s\",\"%s\"", ap, passPhrase) 00088 && _parser.recv("OK"); 00089 } 00090 00091 bool ESP8266::disconnect(void) 00092 { 00093 return _parser.send("AT+CWQAP") && _parser.recv("OK"); 00094 } 00095 00096 const char *ESP8266::getIPAddress(void) 00097 { 00098 if (!(_parser.send("AT+CIFSR") 00099 && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer) 00100 && _parser.recv("OK"))) { 00101 return 0; 00102 } 00103 00104 return _ip_buffer; 00105 } 00106 00107 const char *ESP8266::getMACAddress(void) 00108 { 00109 if (!(_parser.send("AT+CIFSR") 00110 && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer) 00111 && _parser.recv("OK"))) { 00112 return 0; 00113 } 00114 00115 return _mac_buffer; 00116 } 00117 00118 const char *ESP8266::getGateway() 00119 { 00120 if (!(_parser.send("AT+CIPSTA_CUR?") 00121 && _parser.recv("+CIPSTA_CUR:gateway:\"%15[^\"]\"", _gateway_buffer) 00122 && _parser.recv("OK"))) { 00123 return 0; 00124 } 00125 00126 return _gateway_buffer; 00127 } 00128 00129 const char *ESP8266::getNetmask() 00130 { 00131 if (!(_parser.send("AT+CIPSTA_CUR?") 00132 && _parser.recv("+CIPSTA_CUR:netmask:\"%15[^\"]\"", _netmask_buffer) 00133 && _parser.recv("OK"))) { 00134 return 0; 00135 } 00136 00137 return _netmask_buffer; 00138 } 00139 00140 int8_t ESP8266::getRSSI() 00141 { 00142 int8_t rssi; 00143 char bssid[18]; 00144 00145 if (!(_parser.send("AT+CWJAP_CUR?") 00146 && _parser.recv("+CWJAP_CUR::\"%*[^\"]\",\"%17[^\"]\"", bssid) 00147 && _parser.recv("OK"))) { 00148 return 0; 00149 } 00150 00151 if (!(_parser.send("AT+CWLAP=\"\",\"%s\",", bssid) 00152 && _parser.recv("+CWLAP:(%*d,\"%*[^\"]\",%hhd,", &rssi) 00153 && _parser.recv("OK"))) { 00154 return 0; 00155 } 00156 00157 return rssi; 00158 } 00159 00160 bool ESP8266::isConnected(void) 00161 { 00162 return getIPAddress() != 0; 00163 } 00164 00165 int ESP8266::scan(WiFiAccessPoint *res, unsigned limit) 00166 { 00167 unsigned cnt = 0; 00168 nsapi_wifi_ap_t ap; 00169 00170 if (!_parser.send("AT+CWLAP")) { 00171 return NSAPI_ERROR_DEVICE_ERROR; 00172 } 00173 00174 while (recv_ap(&ap)) { 00175 if (cnt < limit) { 00176 res[cnt] = WiFiAccessPoint(ap); 00177 } 00178 00179 cnt++; 00180 if (limit != 0 && cnt >= limit) { 00181 break; 00182 } 00183 } 00184 00185 return cnt; 00186 } 00187 00188 bool ESP8266::open(const char *type, int id, const char* addr, int port) 00189 { 00190 //IDs only 0-4 00191 if(id > 4) { 00192 return false; 00193 } 00194 return _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port) 00195 && _parser.recv("OK"); 00196 } 00197 00198 bool ESP8266::dns_lookup(const char* name, char* ip) 00199 { 00200 return _parser.send("AT+CIPDOMAIN=\"%s\"", name) && _parser.recv("+CIPDOMAIN:%s%*[\r]%*[\n]", ip); 00201 } 00202 00203 bool ESP8266::send(int id, const void *data, uint32_t amount) 00204 { 00205 //May take a second try if device is busy 00206 for (unsigned i = 0; i < 2; i++) { 00207 if (_parser.send("AT+CIPSEND=%d,%d", id, amount) 00208 && _parser.recv(">") 00209 && _parser.write((char*)data, (int)amount) >= 0) { 00210 return true; 00211 } 00212 } 00213 00214 return false; 00215 } 00216 00217 void ESP8266::_packet_handler() 00218 { 00219 int id; 00220 uint32_t amount; 00221 00222 // parse out the packet 00223 if (!_parser.recv(",%d,%d:", &id, &amount)) { 00224 return; 00225 } 00226 00227 struct packet *packet = (struct packet*)malloc( 00228 sizeof(struct packet) + amount); 00229 if (!packet) { 00230 return; 00231 } 00232 00233 packet->id = id; 00234 packet->len = amount; 00235 packet->next = 0; 00236 00237 if (!(_parser.read((char*)(packet + 1), amount))) { 00238 free(packet); 00239 return; 00240 } 00241 00242 // append to packet list 00243 *_packets_end = packet; 00244 _packets_end = &packet->next; 00245 } 00246 00247 int32_t ESP8266::recv(int id, void *data, uint32_t amount) 00248 { 00249 while (true) { 00250 // check if any packets are ready for us 00251 for (struct packet **p = &_packets; *p; p = &(*p)->next) { 00252 if ((*p)->id == id) { 00253 struct packet *q = *p; 00254 00255 if (q->len <= amount) { // Return and remove full packet 00256 memcpy(data, q+1, q->len); 00257 00258 if (_packets_end == &(*p)->next) { 00259 _packets_end = p; 00260 } 00261 *p = (*p)->next; 00262 00263 uint32_t len = q->len; 00264 free(q); 00265 return len; 00266 } else { // return only partial packet 00267 memcpy(data, q+1, amount); 00268 00269 q->len -= amount; 00270 memmove(q+1, (uint8_t*)(q+1) + amount, q->len); 00271 00272 return amount; 00273 } 00274 } 00275 } 00276 00277 // Check for inbound packets 00278 if (!_parser.process_oob()) { 00279 return -1; 00280 } 00281 } 00282 } 00283 00284 bool ESP8266::close(int id) 00285 { 00286 //May take a second try if device is busy 00287 for (unsigned i = 0; i < 2; i++) { 00288 if (_parser.send("AT+CIPCLOSE=%d", id) 00289 && _parser.recv("OK")) { 00290 return true; 00291 } 00292 } 00293 00294 return false; 00295 } 00296 00297 void ESP8266::setTimeout(uint32_t timeout_ms) 00298 { 00299 _parser.set_timeout(timeout_ms); 00300 } 00301 00302 bool ESP8266::readable() 00303 { 00304 return _serial.FileHandle::readable(); 00305 } 00306 00307 bool ESP8266::writeable() 00308 { 00309 return _serial.FileHandle::writable(); 00310 } 00311 00312 void ESP8266::attach(Callback<void()> func) 00313 { 00314 _serial.sigio(func); 00315 } 00316 00317 bool ESP8266::recv_ap(nsapi_wifi_ap_t *ap) 00318 { 00319 int sec; 00320 bool ret = _parser.recv("+CWLAP:(%d,\"%32[^\"]\",%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\",%d", &sec, ap->ssid, 00321 &ap->rssi, &ap->bssid[0], &ap->bssid[1], &ap->bssid[2], &ap->bssid[3], &ap->bssid[4], 00322 &ap->bssid[5], &ap->channel); 00323 00324 ap->security = sec < 5 ? (nsapi_security_t)sec : NSAPI_SECURITY_UNKNOWN; 00325 00326 return ret; 00327 }
Generated on Thu Jul 14 2022 22:28:30 by 1.7.2