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