Added support for WNC M14A2A Cellular LTE Data Module.
Dependencies: WNC14A2AInterface
Dependents: http-example-wnc http-example-wnc-modified
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 17:40:25 by 1.7.2