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