boting ren / Mbed OS BLEClient_mbedDevConn
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 #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 };
00135 
00136 int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
00137 {
00138     // Look for an unused socket
00139     int id = -1;
00140  
00141     for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
00142         if (!_ids[i]) {
00143             id = i;
00144             _ids[i] = true;
00145             break;
00146         }
00147     }
00148  
00149     if (id == -1) {
00150         return NSAPI_ERROR_NO_SOCKET;
00151     }
00152     
00153     struct esp8266_socket *socket = new struct esp8266_socket;
00154     if (!socket) {
00155         return NSAPI_ERROR_NO_SOCKET;
00156     }
00157     
00158     socket->id = id;
00159     socket->proto = proto;
00160     socket->connected = false;
00161     *handle = socket;
00162     return 0;
00163 }
00164 
00165 int ESP8266Interface::socket_close(void *handle)
00166 {
00167     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00168     int err = 0;
00169     _esp.setTimeout(ESP8266_MISC_TIMEOUT);
00170  
00171     if (!_esp.close(socket->id)) {
00172         err = NSAPI_ERROR_DEVICE_ERROR;
00173     }
00174 
00175     _ids[socket->id] = false;
00176     delete socket;
00177     return err;
00178 }
00179 
00180 int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address)
00181 {
00182     return NSAPI_ERROR_UNSUPPORTED;
00183 }
00184 
00185 int ESP8266Interface::socket_listen(void *handle, int backlog)
00186 {
00187     return NSAPI_ERROR_UNSUPPORTED;
00188 }
00189 
00190 int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr)
00191 {
00192     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00193     _esp.setTimeout(ESP8266_MISC_TIMEOUT);
00194 
00195     const char *proto = (socket->proto == NSAPI_UDP) ? "UDP" : "TCP";
00196     if (!_esp.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) {
00197         return NSAPI_ERROR_DEVICE_ERROR;
00198     }
00199     
00200     socket->connected = true;
00201     return 0;
00202 }
00203     
00204 int ESP8266Interface::socket_accept(void *server, void **socket, SocketAddress *addr)
00205 {
00206     return NSAPI_ERROR_UNSUPPORTED;
00207 }
00208 
00209 int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size)
00210 {
00211     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00212     _esp.setTimeout(ESP8266_SEND_TIMEOUT);
00213  
00214     if (!_esp.send(socket->id, data, size)) {
00215         return NSAPI_ERROR_DEVICE_ERROR;
00216     }
00217  
00218     return size;
00219 }
00220 
00221 int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size)
00222 {
00223     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00224     _esp.setTimeout(ESP8266_RECV_TIMEOUT);
00225  
00226     int32_t recv = _esp.recv(socket->id, data, size);
00227     if (recv < 0) {
00228         return NSAPI_ERROR_WOULD_BLOCK;
00229     }
00230  
00231     return recv;
00232 }
00233 
00234 int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
00235 {
00236     struct esp8266_socket *socket = (struct esp8266_socket *)handle;
00237     if (!socket->connected) {
00238         int err = socket_connect(socket, addr);
00239         if (err < 0) {
00240             return err;
00241         }
00242     }
00243     
00244     return socket_send(socket, data, size);
00245 }
00246 
00247 int ESP8266Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
00248 {
00249     struct esp8266_socket *socket = (struct esp8266_socket *)handle;    
00250     return socket_recv(socket, data, size);
00251 }
00252 
00253 void ESP8266Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
00254 {
00255     struct esp8266_socket *socket = (struct esp8266_socket *)handle;    
00256     _cbs[socket->id].callback = callback;
00257     _cbs[socket->id].data = data;
00258 }
00259 
00260 void ESP8266Interface::event() {
00261     for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
00262         if (_cbs[i].callback) {
00263             _cbs[i].callback(_cbs[i].data);
00264         }
00265     }
00266 }