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.
ESP8266Interface.cpp
00001 /* ESP8266 implementation of NetworkInterfaceAPI 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 <string.h> 00018 #include "ESP8266Interface.h" 00019 #include "mbed_debug.h" 00020 00021 // Various timeouts for different ESP8266 operations 00022 #ifndef ESP8266_CONNECT_TIMEOUT 00023 #define ESP8266_CONNECT_TIMEOUT 15000 00024 #endif 00025 #ifndef ESP8266_SEND_TIMEOUT 00026 #define ESP8266_SEND_TIMEOUT 500 00027 #endif 00028 #ifndef ESP8266_RECV_TIMEOUT 00029 #define ESP8266_RECV_TIMEOUT 0 00030 #endif 00031 #ifndef ESP8266_MISC_TIMEOUT 00032 #define ESP8266_MISC_TIMEOUT 500 00033 #endif 00034 00035 // Firmware version 00036 #define ESP8266_VERSION 2 00037 00038 // ESP8266Interface implementation 00039 ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug) 00040 : _esp(tx, rx, debug) 00041 { 00042 memset(_ids, 0, sizeof(_ids)); 00043 memset(_cbs, 0, sizeof(_cbs)); 00044 00045 _esp.attach(this, &ESP8266Interface::event); 00046 } 00047 00048 int ESP8266Interface::connect(const char *ssid, const char *pass, nsapi_security_t security, 00049 uint8_t channel) 00050 { 00051 if (channel != 0) { 00052 return NSAPI_ERROR_UNSUPPORTED; 00053 } 00054 00055 set_credentials(ssid, pass, security); 00056 return connect(); 00057 } 00058 00059 int ESP8266Interface::connect() 00060 { 00061 _esp.setTimeout(ESP8266_CONNECT_TIMEOUT); 00062 00063 if (!_esp.reset()) { 00064 return NSAPI_ERROR_DEVICE_ERROR; 00065 } 00066 00067 _esp.setTimeout(ESP8266_MISC_TIMEOUT); 00068 00069 if (_esp.get_firmware_version() != ESP8266_VERSION) { 00070 debug("ESP8266: ERROR: Firmware incompatible with this driver.\ 00071 \r\nUpdate to v%d - https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update\r\n",ESP8266_VERSION); 00072 return NSAPI_ERROR_DEVICE_ERROR; 00073 } 00074 00075 _esp.setTimeout(ESP8266_CONNECT_TIMEOUT); 00076 00077 if (!_esp.startup(3)) { 00078 return NSAPI_ERROR_DEVICE_ERROR; 00079 } 00080 00081 if (!_esp.dhcp(true, 1)) { 00082 return NSAPI_ERROR_DHCP_FAILURE; 00083 } 00084 00085 if (!_esp.connect(ap_ssid, ap_pass)) { 00086 return NSAPI_ERROR_NO_CONNECTION; 00087 } 00088 00089 if (!_esp.getIPAddress()) { 00090 return NSAPI_ERROR_DHCP_FAILURE; 00091 } 00092 00093 return NSAPI_ERROR_OK; 00094 } 00095 00096 int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) 00097 { 00098 memset(ap_ssid, 0, sizeof(ap_ssid)); 00099 strncpy(ap_ssid, ssid, sizeof(ap_ssid)); 00100 00101 memset(ap_pass, 0, sizeof(ap_pass)); 00102 strncpy(ap_pass, pass, sizeof(ap_pass)); 00103 00104 ap_sec = security; 00105 00106 return 0; 00107 } 00108 00109 int ESP8266Interface::set_channel(uint8_t channel) 00110 { 00111 return NSAPI_ERROR_UNSUPPORTED; 00112 } 00113 00114 00115 int ESP8266Interface::disconnect() 00116 { 00117 _esp.setTimeout(ESP8266_MISC_TIMEOUT); 00118 00119 if (!_esp.disconnect()) { 00120 return NSAPI_ERROR_DEVICE_ERROR; 00121 } 00122 00123 return NSAPI_ERROR_OK; 00124 } 00125 00126 const char *ESP8266Interface::get_ip_address() 00127 { 00128 return _esp.getIPAddress(); 00129 } 00130 00131 const char *ESP8266Interface::get_mac_address() 00132 { 00133 return _esp.getMACAddress(); 00134 } 00135 00136 const char *ESP8266Interface::get_gateway() 00137 { 00138 return _esp.getGateway(); 00139 } 00140 00141 const char *ESP8266Interface::get_netmask() 00142 { 00143 return _esp.getNetmask(); 00144 } 00145 00146 int8_t ESP8266Interface::get_rssi() 00147 { 00148 return _esp.getRSSI(); 00149 } 00150 00151 int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count) 00152 { 00153 return _esp.scan(res, count); 00154 } 00155 00156 struct esp8266_socket { 00157 int id; 00158 nsapi_protocol_t proto; 00159 bool connected; 00160 SocketAddress addr; 00161 }; 00162 00163 int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto) 00164 { 00165 // Look for an unused socket 00166 int id = -1; 00167 00168 for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) { 00169 if (!_ids[i]) { 00170 id = i; 00171 _ids[i] = true; 00172 break; 00173 } 00174 } 00175 00176 if (id == -1) { 00177 return NSAPI_ERROR_NO_SOCKET; 00178 } 00179 00180 struct esp8266_socket *socket = new struct esp8266_socket; 00181 if (!socket) { 00182 return NSAPI_ERROR_NO_SOCKET; 00183 } 00184 00185 socket->id = id; 00186 socket->proto = proto; 00187 socket->connected = false; 00188 *handle = socket; 00189 return 0; 00190 } 00191 00192 int ESP8266Interface::socket_close(void *handle) 00193 { 00194 struct esp8266_socket *socket = (struct esp8266_socket *)handle; 00195 int err = 0; 00196 _esp.setTimeout(ESP8266_MISC_TIMEOUT); 00197 00198 if (socket->connected && !_esp.close(socket->id)) { 00199 err = NSAPI_ERROR_DEVICE_ERROR; 00200 } 00201 00202 socket->connected = false; 00203 _ids[socket->id] = false; 00204 delete socket; 00205 return err; 00206 } 00207 00208 int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address) 00209 { 00210 return NSAPI_ERROR_UNSUPPORTED; 00211 } 00212 00213 int ESP8266Interface::socket_listen(void *handle, int backlog) 00214 { 00215 return NSAPI_ERROR_UNSUPPORTED; 00216 } 00217 00218 int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr) 00219 { 00220 struct esp8266_socket *socket = (struct esp8266_socket *)handle; 00221 _esp.setTimeout(ESP8266_MISC_TIMEOUT); 00222 00223 const char *proto = (socket->proto == NSAPI_UDP) ? "UDP" : "TCP"; 00224 if (!_esp.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) { 00225 return NSAPI_ERROR_DEVICE_ERROR; 00226 } 00227 00228 socket->connected = true; 00229 return 0; 00230 } 00231 00232 int ESP8266Interface::socket_accept(void *server, void **socket, SocketAddress *addr) 00233 { 00234 return NSAPI_ERROR_UNSUPPORTED; 00235 } 00236 00237 int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size) 00238 { 00239 struct esp8266_socket *socket = (struct esp8266_socket *)handle; 00240 _esp.setTimeout(ESP8266_SEND_TIMEOUT); 00241 00242 if (!_esp.send(socket->id, data, size)) { 00243 return NSAPI_ERROR_DEVICE_ERROR; 00244 } 00245 00246 return size; 00247 } 00248 00249 int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size) 00250 { 00251 struct esp8266_socket *socket = (struct esp8266_socket *)handle; 00252 _esp.setTimeout(ESP8266_RECV_TIMEOUT); 00253 00254 int32_t recv = _esp.recv(socket->id, data, size); 00255 if (recv < 0) { 00256 return NSAPI_ERROR_WOULD_BLOCK; 00257 } 00258 00259 return recv; 00260 } 00261 00262 int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) 00263 { 00264 struct esp8266_socket *socket = (struct esp8266_socket *)handle; 00265 00266 if (socket->connected && socket->addr != addr) { 00267 _esp.setTimeout(ESP8266_MISC_TIMEOUT); 00268 if (!_esp.close(socket->id)) { 00269 return NSAPI_ERROR_DEVICE_ERROR; 00270 } 00271 socket->connected = false; 00272 } 00273 00274 if (!socket->connected) { 00275 int err = socket_connect(socket, addr); 00276 if (err < 0) { 00277 return err; 00278 } 00279 socket->addr = addr; 00280 } 00281 00282 return socket_send(socket, data, size); 00283 } 00284 00285 int ESP8266Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) 00286 { 00287 struct esp8266_socket *socket = (struct esp8266_socket *)handle; 00288 int ret = socket_recv(socket, data, size); 00289 if (ret >= 0 && addr) { 00290 *addr = socket->addr; 00291 } 00292 00293 return ret; 00294 } 00295 00296 void ESP8266Interface::socket_attach(void *handle, void (*callback)(void *), void *data) 00297 { 00298 struct esp8266_socket *socket = (struct esp8266_socket *)handle; 00299 _cbs[socket->id].callback = callback; 00300 _cbs[socket->id].data = data; 00301 } 00302 00303 void ESP8266Interface::event() { 00304 for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) { 00305 if (_cbs[i].callback) { 00306 _cbs[i].callback(_cbs[i].data); 00307 } 00308 } 00309 }
Generated on Tue Jul 12 2022 15:14:29 by
1.7.2