Socket interface for ESP8266. Implements the NetworkSocketAPI. Requires device to use the Espressif Firmware.

Dependencies:   ESP8266

Dependents:   ESP8266InterfaceTests HelloESP8266Interface

Fork of ESP8266Interface by NetworkSocketAPI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ESP8266Interface.cpp Source File

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 
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 
00027 // ESP8266Interface implementation
00028 ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug)
00029     : _esp(tx, rx, debug)
00030 {
00031     memset(_ids, 0, sizeof(_ids));
00032 }
00033 
00034 int ESP8266Interface::connect(
00035     const char *ssid,
00036     const char *pass,
00037     nsapi_security_t security)
00038 {
00039     _esp.setTimeout(ESP8266_CONNECT_TIMEOUT);
00040 
00041     if (!_esp.startup(3)) {
00042         return NSAPI_ERROR_DEVICE_ERROR;
00043     }
00044 
00045     if (!_esp.dhcp(true, 1)) {
00046         return NSAPI_ERROR_DHCP_FAILURE;
00047     }
00048 
00049     if (!_esp.connect(ssid, pass)) {
00050         return NSAPI_ERROR_NO_CONNECTION;
00051     }
00052 
00053     if (!_esp.getIPAddress()) {
00054         return NSAPI_ERROR_DHCP_FAILURE;
00055     }
00056 
00057     return 0;
00058 }
00059 
00060 int ESP8266Interface::disconnect()
00061 {
00062     _esp.setTimeout(ESP8266_MISC_TIMEOUT);
00063 
00064     if (!_esp.disconnect()) {
00065         return NSAPI_ERROR_DEVICE_ERROR;
00066     }
00067 
00068     return 0;
00069 }
00070 
00071 const char *ESP8266Interface::get_ip_address()
00072 {
00073     return _esp.getIPAddress();
00074 }
00075 
00076 const char *ESP8266Interface::get_mac_address()
00077 {
00078     return _esp.getMACAddress();
00079 }
00080 
00081 struct esp8266_socket {
00082     int id;
00083     nsapi_protocol_t proto;
00084     bool connected;
00085 };
00086 
00087 int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
00088 {
00089     // Look for an unused socket
00090     int id = -1;
00091  
00092     for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
00093         if (!_ids[i]) {
00094             id = i;
00095             _ids[i] = true;
00096             break;
00097         }
00098     }
00099  
00100     if (id == -1) {
00101         return NSAPI_ERROR_NO_SOCKET;
00102     }
00103     
00104     struct esp8266_socket *socket = new struct esp8266_socket;
00105     if (!socket) {
00106         return NSAPI_ERROR_NO_SOCKET;
00107     }
00108     
00109     socket->id = id;
00110     socket->proto = proto;
00111     socket->connected = false;
00112     *handle = socket;
00113     return 0;
00114 }
00115 
00116 int ESP8266Interface::socket_close(void *handle)
00117 {
00118     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00119     int err = 0;
00120     _esp.setTimeout(ESP8266_MISC_TIMEOUT);
00121  
00122     if (!_esp.close(socket->id)) {
00123         err = NSAPI_ERROR_DEVICE_ERROR;
00124     }
00125 
00126     _ids[socket->id] = false;
00127     delete socket;
00128     return err;
00129 }
00130 
00131 int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address)
00132 {
00133     return NSAPI_ERROR_UNSUPPORTED;
00134 }
00135 
00136 int ESP8266Interface::socket_listen(void *handle, int backlog)
00137 {
00138     return NSAPI_ERROR_UNSUPPORTED;
00139 }
00140 
00141 int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr)
00142 {
00143     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00144     _esp.setTimeout(ESP8266_MISC_TIMEOUT);
00145 
00146     const char *proto = (socket->proto == NSAPI_UDP) ? "UDP" : "TCP";
00147     if (!_esp.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) {
00148         return NSAPI_ERROR_DEVICE_ERROR;
00149     }
00150     
00151     socket->connected = true;
00152     return 0;
00153 }
00154     
00155 int ESP8266Interface::socket_accept(void **handle, void *server)
00156 {
00157     return NSAPI_ERROR_UNSUPPORTED;
00158 }
00159 
00160 int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size)
00161 {
00162     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00163     _esp.setTimeout(ESP8266_SEND_TIMEOUT);
00164  
00165     if (!_esp.send(socket->id, data, size)) {
00166         return NSAPI_ERROR_DEVICE_ERROR;
00167     }
00168  
00169     return size;
00170 }
00171 
00172 int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size)
00173 {
00174     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00175     _esp.setTimeout(ESP8266_RECV_TIMEOUT);
00176  
00177     int32_t recv = _esp.recv(socket->id, data, size);
00178     if (recv < 0) {
00179         return NSAPI_ERROR_WOULD_BLOCK;
00180     }
00181  
00182     return recv;
00183 }
00184 
00185 int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
00186 {
00187     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00188     if (!socket->connected) {
00189         int err = socket_connect(socket, addr);
00190         if (err < 0) {
00191             return err;
00192         }
00193     }
00194     
00195     return socket_send(socket, data, size);
00196 }
00197 
00198 int ESP8266Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
00199 {
00200     struct esp8266_socket *socket = (struct esp8266_socket *)handle;    
00201     return socket_recv(socket, data, size);
00202 }
00203 
00204 void ESP8266Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
00205 {
00206 }