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