test public

Dependencies:   HttpServer_snapshot_mbed-os

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ESP32Stack.cpp Source File

ESP32Stack.cpp

00001 /* ESP32 implementation of NetworkInterfaceAPI
00002  * Copyright (c) 2015 ARM Limited
00003  * Copyright (c) 2017 Renesas Electronics Corporation
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include <string.h>
00019 #include "ESP32Stack.h"
00020 
00021 // ESP32Stack implementation
00022 ESP32Stack::ESP32Stack(PinName en, PinName io0, PinName tx, PinName rx, bool debug,
00023     PinName rts, PinName cts, int baudrate, int is_ap) : _is_ap(is_ap)
00024 {
00025     _esp = ESP32::getESP32Inst(en, io0, tx, rx, debug, rts, cts, baudrate);
00026     memset(_local_ports, 0, sizeof(_local_ports));
00027 }
00028 
00029 struct esp32_socket {
00030     int id;
00031     nsapi_protocol_t proto;
00032     bool connected;
00033     SocketAddress addr;
00034     int keepalive; // TCP
00035     bool accept_id;
00036     bool tcp_server;
00037 };
00038 
00039 int ESP32Stack::socket_open(void **handle, nsapi_protocol_t proto)
00040 {
00041     // Look for an unused socket
00042     int id = _esp->get_free_id();
00043 
00044     if (id == -1) {
00045         return NSAPI_ERROR_NO_SOCKET;
00046     }
00047 
00048     struct esp32_socket *socket = new struct esp32_socket;
00049     if (!socket) {
00050         return NSAPI_ERROR_NO_SOCKET;
00051     }
00052 
00053     socket->id = id;
00054     socket->proto = proto;
00055     socket->connected = false;
00056     socket->keepalive = 0;
00057     socket->accept_id = false;
00058     socket->tcp_server = false;
00059     *handle = socket;
00060     _local_ports[socket->id] = 0;
00061     return 0;
00062 }
00063 
00064 int ESP32Stack::socket_close(void *handle)
00065 {
00066     struct esp32_socket *socket = (struct esp32_socket *)handle;
00067     int err = 0;
00068 
00069     if (!socket) {
00070         return NSAPI_ERROR_NO_SOCKET;
00071     }
00072 
00073     if (!_esp->close(socket->id, socket->accept_id)) {
00074         err = NSAPI_ERROR_DEVICE_ERROR;
00075     }
00076 
00077     if (socket->tcp_server) {
00078         _esp->del_server();
00079     }
00080     _local_ports[socket->id] = 0;
00081 
00082     delete socket;
00083     return err;
00084 }
00085 
00086 int ESP32Stack::socket_bind(void *handle, const SocketAddress &address)
00087 {
00088     struct esp32_socket *socket = (struct esp32_socket *)handle;
00089 
00090     if (!socket) {
00091         return NSAPI_ERROR_NO_SOCKET;
00092     }
00093 
00094     if (address.get_ip_address() != NULL) {
00095         if (_is_ap == 0) {
00096             if (strncmp(address.get_ip_address(), _esp->getIPAddress(), NSAPI_IPv6_SIZE) != 0) {
00097                 return NSAPI_ERROR_PARAMETER;
00098             }
00099         } else {
00100             if (strncmp(address.get_ip_address(), _esp->getIPAddress_ap(), NSAPI_IPv6_SIZE) != 0) {
00101                 return NSAPI_ERROR_PARAMETER;
00102             }
00103         }
00104     }
00105 
00106     if(address.get_addr().version != NSAPI_UNSPEC) {
00107         return NSAPI_ERROR_UNSUPPORTED;
00108     }
00109 
00110     for(int id = 0; id < ESP32::SOCKET_COUNT; id++) {
00111         if(_local_ports[id] == address.get_port() && id != socket->id) { // Port already reserved by another socket
00112             return NSAPI_ERROR_PARAMETER;
00113         } else if (id == socket->id && socket->connected) {
00114             return NSAPI_ERROR_PARAMETER;
00115         }
00116     }
00117     _local_ports[socket->id] = address.get_port();
00118     socket->addr = address;
00119     return 0;
00120 }
00121 
00122 int ESP32Stack::socket_listen(void *handle, int backlog)
00123 {
00124     struct esp32_socket *socket = (struct esp32_socket *)handle;
00125 
00126     (void)backlog;
00127 
00128     if (!socket) {
00129         return NSAPI_ERROR_NO_SOCKET;
00130     }
00131 
00132     if (socket->proto != NSAPI_TCP) {
00133         return NSAPI_ERROR_UNSUPPORTED;
00134     }
00135 
00136     if (!_esp->cre_server(socket->addr.get_port())) {
00137         return NSAPI_ERROR_DEVICE_ERROR;
00138     }
00139 
00140     socket->tcp_server = true;
00141     return 0;
00142 }
00143 
00144 int ESP32Stack::socket_connect(void *handle, const SocketAddress &addr)
00145 {
00146     struct esp32_socket *socket = (struct esp32_socket *)handle;
00147 
00148     if (!socket) {
00149         return NSAPI_ERROR_NO_SOCKET;
00150     }
00151 
00152     if (socket->proto == NSAPI_UDP) {
00153         if (!_esp->open("UDP", socket->id, addr.get_ip_address(), addr.get_port(), _local_ports[socket->id])) {
00154             return NSAPI_ERROR_DEVICE_ERROR;
00155         }
00156     } else {
00157         if (!_esp->open("TCP", socket->id, addr.get_ip_address(), addr.get_port(), socket->keepalive)) {
00158             return NSAPI_ERROR_DEVICE_ERROR;
00159         }
00160     }
00161 
00162     socket->connected = true;
00163     return 0;
00164 }
00165 
00166 int ESP32Stack::socket_accept(void *server, void **socket, SocketAddress *addr)
00167 {
00168     struct esp32_socket *socket_new = new struct esp32_socket;
00169     int id;
00170 
00171     if (!socket_new) {
00172         return NSAPI_ERROR_NO_SOCKET;
00173     }
00174 
00175     if (!_esp->accept(&id)) {
00176         delete socket_new;
00177         return NSAPI_ERROR_NO_SOCKET;
00178     }
00179 
00180     socket_new->id = id;
00181     socket_new->proto = NSAPI_TCP;
00182     socket_new->connected = true;
00183     socket_new->accept_id = true;
00184     socket_new->tcp_server = false;
00185     *socket = socket_new;
00186 
00187     return 0;
00188 }
00189 
00190 int ESP32Stack::socket_send(void *handle, const void *data, unsigned size)
00191 {
00192     struct esp32_socket *socket = (struct esp32_socket *)handle;
00193 
00194     if (!socket) {
00195         return NSAPI_ERROR_NO_SOCKET;
00196     }
00197 
00198     if (!_esp->send(socket->id, data, size)) {
00199         return NSAPI_ERROR_DEVICE_ERROR;
00200     }
00201 
00202     return size;
00203 }
00204 
00205 int ESP32Stack::socket_recv(void *handle, void *data, unsigned size)
00206 {
00207     struct esp32_socket *socket = (struct esp32_socket *)handle;
00208 
00209     if (!socket) {
00210         return NSAPI_ERROR_NO_SOCKET;
00211     }
00212 
00213     int32_t recv = _esp->recv(socket->id, data, size);
00214     if (recv == -1) {
00215         return NSAPI_ERROR_WOULD_BLOCK;
00216     }
00217 
00218     return recv;
00219 }
00220 
00221 int ESP32Stack::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
00222 {
00223     struct esp32_socket *socket = (struct esp32_socket *)handle;
00224 
00225     if (!socket) {
00226         return NSAPI_ERROR_NO_SOCKET;
00227     }
00228 
00229     if (socket->connected && socket->addr != addr) {
00230         if (!_esp->close(socket->id, socket->accept_id)) {
00231             return NSAPI_ERROR_DEVICE_ERROR;
00232         }
00233         socket->connected = false;
00234     }
00235 
00236     if (!socket->connected) {
00237         int err = socket_connect(socket, addr);
00238         if (err < 0) {
00239             return err;
00240         }
00241         socket->addr = addr;
00242     }
00243     
00244     return socket_send(socket, data, size);
00245 }
00246 
00247 int ESP32Stack::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
00248 {
00249     struct esp32_socket *socket = (struct esp32_socket *)handle;
00250 
00251     if (!socket) {
00252         return NSAPI_ERROR_NO_SOCKET;
00253     }
00254 
00255     int ret = socket_recv(socket, data, size);
00256     if (ret >= 0 && addr) {
00257         *addr = socket->addr;
00258     }
00259 
00260     return ret;
00261 }
00262 
00263 void ESP32Stack::socket_attach(void *handle, void (*callback)(void *), void *data)
00264 {
00265     struct esp32_socket *socket = (struct esp32_socket *)handle;
00266 
00267     if (!socket) {
00268         return;
00269     }
00270 
00271     _esp->socket_attach(socket->id, callback, data);
00272 }
00273 
00274 nsapi_error_t ESP32Stack::setsockopt(nsapi_socket_t handle, int level, 
00275         int optname, const void *optval, unsigned optlen)
00276 {
00277     struct esp32_socket *socket = (struct esp32_socket *)handle;
00278 
00279     if (!optlen) {
00280         return NSAPI_ERROR_PARAMETER;
00281     } else if (!socket) {
00282         return NSAPI_ERROR_NO_SOCKET;
00283     }
00284 
00285     if (level == NSAPI_SOCKET && socket->proto == NSAPI_TCP) {
00286         switch (optname) {
00287             case NSAPI_KEEPALIVE: {
00288                 if(socket->connected) {// ESP32 limitation, keepalive needs to be given before connecting
00289                     return NSAPI_ERROR_UNSUPPORTED;
00290                 }
00291 
00292                 if (optlen == sizeof(int)) {
00293                     int secs = *(int *)optval;
00294                     if (secs  >= 0 && secs <= 7200) {
00295                         socket->keepalive = secs;
00296                         return NSAPI_ERROR_OK;
00297                     }
00298                 }
00299                 return NSAPI_ERROR_PARAMETER;
00300             }
00301         }
00302     }
00303 
00304     return NSAPI_ERROR_UNSUPPORTED;
00305 }
00306 
00307 nsapi_error_t ESP32Stack::getsockopt(nsapi_socket_t handle, int level,
00308         int optname, void *optval, unsigned *optlen)
00309 {
00310     struct esp32_socket *socket = (struct esp32_socket *)handle;
00311 
00312     if (!optval || !optlen) {
00313         return NSAPI_ERROR_PARAMETER;
00314     } else if (!socket) {
00315         return NSAPI_ERROR_NO_SOCKET;
00316     }
00317 
00318     if (level == NSAPI_SOCKET && socket->proto == NSAPI_TCP) {
00319         switch (optname) {
00320             case NSAPI_KEEPALIVE: {
00321                 if(*optlen > sizeof(int)) {
00322                     *optlen = sizeof(int);
00323                 }
00324                 memcpy(optval, &(socket->keepalive), *optlen);
00325                 return NSAPI_ERROR_OK;
00326             }
00327         }
00328     }
00329 
00330     return NSAPI_ERROR_UNSUPPORTED;
00331 }
00332