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.
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) 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 return 0; 00061 } 00062 00063 int ESP32Stack::socket_close(void *handle) 00064 { 00065 struct esp32_socket *socket = (struct esp32_socket *)handle; 00066 int err = 0; 00067 00068 if (!socket) { 00069 return NSAPI_ERROR_NO_SOCKET; 00070 } 00071 00072 if (!_esp->close(socket->id, socket->accept_id)) { 00073 err = NSAPI_ERROR_DEVICE_ERROR; 00074 } 00075 00076 if (socket->tcp_server) { 00077 _esp->del_server(); 00078 } 00079 _local_ports[socket->id] = 0; 00080 00081 delete socket; 00082 return err; 00083 } 00084 00085 int ESP32Stack::socket_bind(void *handle, const SocketAddress &address) 00086 { 00087 struct esp32_socket *socket = (struct esp32_socket *)handle; 00088 00089 if (!socket) { 00090 return NSAPI_ERROR_NO_SOCKET; 00091 } 00092 00093 if (socket->proto == NSAPI_UDP) { 00094 if(address.get_addr().version != NSAPI_UNSPEC) { 00095 return NSAPI_ERROR_UNSUPPORTED; 00096 } 00097 00098 for(int id = 0; id < ESP32::SOCKET_COUNT; id++) { 00099 if(_local_ports[id] == address.get_port() && id != socket->id) { // Port already reserved by another socket 00100 return NSAPI_ERROR_PARAMETER; 00101 } else if (id == socket->id && socket->connected) { 00102 return NSAPI_ERROR_PARAMETER; 00103 } 00104 } 00105 _local_ports[socket->id] = address.get_port(); 00106 return 0; 00107 } 00108 00109 socket->addr = address; 00110 return 0; 00111 } 00112 00113 int ESP32Stack::socket_listen(void *handle, int backlog) 00114 { 00115 struct esp32_socket *socket = (struct esp32_socket *)handle; 00116 00117 (void)backlog; 00118 00119 if (!socket) { 00120 return NSAPI_ERROR_NO_SOCKET; 00121 } 00122 00123 if (socket->proto != NSAPI_TCP) { 00124 return NSAPI_ERROR_UNSUPPORTED; 00125 } 00126 00127 if (!_esp->cre_server(socket->addr.get_port())) { 00128 return NSAPI_ERROR_DEVICE_ERROR; 00129 } 00130 00131 socket->tcp_server = true; 00132 return 0; 00133 } 00134 00135 int ESP32Stack::socket_connect(void *handle, const SocketAddress &addr) 00136 { 00137 struct esp32_socket *socket = (struct esp32_socket *)handle; 00138 00139 if (!socket) { 00140 return NSAPI_ERROR_NO_SOCKET; 00141 } 00142 00143 if (socket->proto == NSAPI_UDP) { 00144 if (!_esp->open("UDP", socket->id, addr.get_ip_address(), addr.get_port(), _local_ports[socket->id])) { 00145 return NSAPI_ERROR_DEVICE_ERROR; 00146 } 00147 } else { 00148 if (!_esp->open("TCP", socket->id, addr.get_ip_address(), addr.get_port(), socket->keepalive)) { 00149 return NSAPI_ERROR_DEVICE_ERROR; 00150 } 00151 } 00152 00153 socket->connected = true; 00154 return 0; 00155 } 00156 00157 int ESP32Stack::socket_accept(void *server, void **socket, SocketAddress *addr) 00158 { 00159 struct esp32_socket *socket_new = new struct esp32_socket; 00160 int id; 00161 00162 if (!socket_new) { 00163 return NSAPI_ERROR_NO_SOCKET; 00164 } 00165 00166 if (!_esp->accept(&id)) { 00167 delete socket_new; 00168 return NSAPI_ERROR_NO_SOCKET; 00169 } 00170 00171 socket_new->id = id; 00172 socket_new->proto = NSAPI_TCP; 00173 socket_new->connected = true; 00174 socket_new->accept_id = true; 00175 socket_new->tcp_server = false; 00176 *socket = socket_new; 00177 00178 return 0; 00179 } 00180 00181 int ESP32Stack::socket_send(void *handle, const void *data, unsigned size) 00182 { 00183 struct esp32_socket *socket = (struct esp32_socket *)handle; 00184 00185 if (!socket) { 00186 return NSAPI_ERROR_NO_SOCKET; 00187 } 00188 00189 if (!_esp->send(socket->id, data, size)) { 00190 return NSAPI_ERROR_DEVICE_ERROR; 00191 } 00192 00193 return size; 00194 } 00195 00196 int ESP32Stack::socket_recv(void *handle, void *data, unsigned size) 00197 { 00198 struct esp32_socket *socket = (struct esp32_socket *)handle; 00199 00200 if (!socket) { 00201 return NSAPI_ERROR_NO_SOCKET; 00202 } 00203 00204 int32_t recv = _esp->recv(socket->id, data, size); 00205 if (recv == -1) { 00206 return NSAPI_ERROR_WOULD_BLOCK; 00207 } else if (recv < 0) { 00208 return NSAPI_ERROR_NO_SOCKET; 00209 } else { 00210 // do nothing 00211 } 00212 00213 return recv; 00214 } 00215 00216 int ESP32Stack::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) 00217 { 00218 struct esp32_socket *socket = (struct esp32_socket *)handle; 00219 00220 if (!socket) { 00221 return NSAPI_ERROR_NO_SOCKET; 00222 } 00223 00224 if (socket->connected && socket->addr != addr) { 00225 if (!_esp->close(socket->id, socket->accept_id)) { 00226 return NSAPI_ERROR_DEVICE_ERROR; 00227 } 00228 socket->connected = false; 00229 } 00230 00231 if (!socket->connected) { 00232 int err = socket_connect(socket, addr); 00233 if (err < 0) { 00234 return err; 00235 } 00236 socket->addr = addr; 00237 } 00238 00239 return socket_send(socket, data, size); 00240 } 00241 00242 int ESP32Stack::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) 00243 { 00244 struct esp32_socket *socket = (struct esp32_socket *)handle; 00245 00246 if (!socket) { 00247 return NSAPI_ERROR_NO_SOCKET; 00248 } 00249 00250 int ret = socket_recv(socket, data, size); 00251 if (ret >= 0 && addr) { 00252 *addr = socket->addr; 00253 } 00254 00255 return ret; 00256 } 00257 00258 void ESP32Stack::socket_attach(void *handle, void (*callback)(void *), void *data) 00259 { 00260 struct esp32_socket *socket = (struct esp32_socket *)handle; 00261 00262 if (!socket) { 00263 return; 00264 } 00265 00266 _esp->socket_attach(socket->id, callback, data); 00267 } 00268 00269 nsapi_error_t ESP32Stack::setsockopt(nsapi_socket_t handle, int level, 00270 int optname, const void *optval, unsigned optlen) 00271 { 00272 struct esp32_socket *socket = (struct esp32_socket *)handle; 00273 00274 if (!optlen) { 00275 return NSAPI_ERROR_PARAMETER; 00276 } else if (!socket) { 00277 return NSAPI_ERROR_NO_SOCKET; 00278 } 00279 00280 if (level == NSAPI_SOCKET && socket->proto == NSAPI_TCP) { 00281 switch (optname) { 00282 case NSAPI_KEEPALIVE: { 00283 if(socket->connected) {// ESP32 limitation, keepalive needs to be given before connecting 00284 return NSAPI_ERROR_UNSUPPORTED; 00285 } 00286 00287 if (optlen == sizeof(int)) { 00288 int secs = *(int *)optval; 00289 if (secs >= 0 && secs <= 7200) { 00290 socket->keepalive = secs; 00291 return NSAPI_ERROR_OK; 00292 } 00293 } 00294 return NSAPI_ERROR_PARAMETER; 00295 } 00296 } 00297 } 00298 00299 return NSAPI_ERROR_UNSUPPORTED; 00300 } 00301 00302 nsapi_error_t ESP32Stack::getsockopt(nsapi_socket_t handle, int level, 00303 int optname, void *optval, unsigned *optlen) 00304 { 00305 struct esp32_socket *socket = (struct esp32_socket *)handle; 00306 00307 if (!optval || !optlen) { 00308 return NSAPI_ERROR_PARAMETER; 00309 } else if (!socket) { 00310 return NSAPI_ERROR_NO_SOCKET; 00311 } 00312 00313 if (level == NSAPI_SOCKET && socket->proto == NSAPI_TCP) { 00314 switch (optname) { 00315 case NSAPI_KEEPALIVE: { 00316 if(*optlen > sizeof(int)) { 00317 *optlen = sizeof(int); 00318 } 00319 memcpy(optval, &(socket->keepalive), *optlen); 00320 return NSAPI_ERROR_OK; 00321 } 00322 } 00323 } 00324 00325 return NSAPI_ERROR_UNSUPPORTED; 00326 } 00327
Generated on Tue Jul 12 2022 16:59:38 by
1.7.2