Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
web_socket_transport.c
Go to the documentation of this file.
00001 /** 00002 * @file web_socket_transport.c 00003 * @brief WebSocket transport layer 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL WEB_SOCKET_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include "core/net.h" 00034 #include "web_socket/web_socket.h" 00035 #include "web_socket/web_socket_transport.h" 00036 #include "debug.h" 00037 00038 //Check TCP/IP stack configuration 00039 #if (WEB_SOCKET_SUPPORT == ENABLED) 00040 00041 00042 /** 00043 * @brief Open network connection 00044 * @param[in] webSocket Handle to a WebSocket 00045 * @return Error code 00046 **/ 00047 00048 error_t webSocketOpenConnection(WebSocket *webSocket) 00049 { 00050 error_t error; 00051 00052 //Invalid socket handle? 00053 if(webSocket->socket == NULL) 00054 { 00055 //Open a TCP socket 00056 webSocket->socket = socketOpen(SOCKET_TYPE_STREAM, SOCKET_IP_PROTO_TCP); 00057 //Failed to open socket? 00058 if(webSocket->socket == NULL) 00059 return ERROR_OPEN_FAILED; 00060 00061 //Associate the WebSocket with the relevant interface 00062 error = socketBindToInterface(webSocket->socket, webSocket->interface); 00063 //Any error to report? 00064 if(error) 00065 return error; 00066 } 00067 00068 //Set timeout 00069 error = socketSetTimeout(webSocket->socket, webSocket->timeout); 00070 //Any error to report? 00071 if(error) 00072 return error; 00073 00074 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED) 00075 //Use SSL/TLS to secure the connection? 00076 if(webSocket->tlsInitCallback != NULL) 00077 { 00078 TlsConnectionEnd connectionEnd; 00079 00080 //Allocate SSL/TLS context 00081 webSocket->tlsContext = tlsInit(); 00082 //Failed to allocate SSL/TLS context? 00083 if(webSocket->tlsContext == NULL) 00084 return ERROR_OUT_OF_MEMORY; 00085 00086 //Client or server operation? 00087 if(webSocket->endpoint == WS_ENDPOINT_CLIENT) 00088 connectionEnd = TLS_CONNECTION_END_CLIENT; 00089 else 00090 connectionEnd = TLS_CONNECTION_END_SERVER; 00091 00092 //Select the relevant operation mode 00093 error = tlsSetConnectionEnd(webSocket->tlsContext, connectionEnd); 00094 //Any error to report? 00095 if(error) 00096 return error; 00097 00098 //Bind TLS to the relevant socket 00099 error = tlsSetSocket(webSocket->tlsContext, webSocket->socket); 00100 //Any error to report? 00101 if(error) 00102 return error; 00103 00104 //Restore SSL/TLS session, if any 00105 if(webSocket->tlsSession.idLength > 0) 00106 { 00107 //Restore SSL/TLS session 00108 error = tlsRestoreSession(webSocket->tlsContext, &webSocket->tlsSession); 00109 //Any error to report? 00110 if(error) 00111 return error; 00112 } 00113 00114 //Invoke user-defined callback, if any 00115 if(webSocket->tlsInitCallback != NULL) 00116 { 00117 //Perform SSL/TLS related initialization 00118 error = webSocket->tlsInitCallback(webSocket, webSocket->tlsContext); 00119 //Any error to report? 00120 if(error) 00121 return error; 00122 } 00123 } 00124 #endif 00125 00126 //Successful initialization 00127 return NO_ERROR; 00128 } 00129 00130 00131 /** 00132 * @brief Establish network connection 00133 * @param[in] webSocket Handle to a WebSocket 00134 * @param[in] serverIpAddr IP address of the WebSocket server to connect to 00135 * @param[in] serverPort TCP port number that will be used to establish the 00136 * connection 00137 * @return Error code 00138 **/ 00139 00140 error_t webSocketEstablishConnection(WebSocket *webSocket, 00141 const IpAddr *serverIpAddr, uint16_t serverPort) 00142 { 00143 error_t error; 00144 00145 //Connect to WebSocket server 00146 error = socketConnect(webSocket->socket, serverIpAddr, serverPort); 00147 00148 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED) 00149 //Use SSL/TLS to secure the connection? 00150 if(webSocket->tlsInitCallback != NULL) 00151 { 00152 //Check status code 00153 if(!error) 00154 { 00155 //Establish a SSL/TLS connection 00156 error = tlsConnect(webSocket->tlsContext); 00157 } 00158 } 00159 #endif 00160 00161 //Return status code 00162 return error; 00163 } 00164 00165 00166 /** 00167 * @brief Shutdown network connection 00168 * @param[in] webSocket Handle to a WebSocket 00169 * @return Error code 00170 **/ 00171 00172 error_t webSocketShutdownConnection(WebSocket *webSocket) 00173 { 00174 error_t error; 00175 size_t n; 00176 00177 //Initialize status code 00178 error = NO_ERROR; 00179 00180 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED) 00181 //Check whether a secure connection is being used 00182 if(webSocket->tlsContext != NULL) 00183 { 00184 //Shutdown SSL/TLS connection 00185 error = tlsShutdown(webSocket->tlsContext); 00186 } 00187 #endif 00188 00189 //Check status code 00190 if(!error) 00191 { 00192 //Further transmissions are disallowed 00193 error = socketShutdown(webSocket->socket, SOCKET_SD_SEND); 00194 } 00195 00196 //Receive data until until the peer has also performed an orderly shutdown 00197 while(!error) 00198 { 00199 //Discard data 00200 error = socketReceive(webSocket->socket, webSocket->rxContext.buffer, 00201 WEB_SOCKET_BUFFER_SIZE, &n, 0); 00202 } 00203 00204 //Check whether the connection has been properly closed 00205 if(error == ERROR_END_OF_STREAM) 00206 error = NO_ERROR; 00207 00208 //Return status code 00209 return error; 00210 } 00211 00212 00213 /** 00214 * @brief Close network connection 00215 * @param[in] webSocket Handle to a WebSocket 00216 **/ 00217 00218 void webSocketCloseConnection(WebSocket *webSocket) 00219 { 00220 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED) 00221 //Check whether a secure connection is being used 00222 if(webSocket->tlsContext != NULL) 00223 { 00224 //Save SSL/TLS session 00225 tlsSaveSession(webSocket->tlsContext, &webSocket->tlsSession); 00226 00227 //Release SSL/TLS context 00228 tlsFree(webSocket->tlsContext); 00229 webSocket->tlsContext = NULL; 00230 } 00231 #endif 00232 00233 //Close TCP connection 00234 if(webSocket->socket != NULL) 00235 { 00236 socketClose(webSocket->socket); 00237 webSocket->socket = NULL; 00238 } 00239 } 00240 00241 00242 /** 00243 * @brief Send data using the relevant transport protocol 00244 * @param[in] webSocket Handle to a WebSocket 00245 * @param[in] data Pointer to a buffer containing the data to be transmitted 00246 * @param[in] length Number of bytes to be transmitted 00247 * @param[out] written Actual number of bytes written (optional parameter) 00248 * @param[in] flags Set of flags that influences the behavior of this function 00249 * @return Error code 00250 **/ 00251 00252 error_t webSocketSendData(WebSocket *webSocket, const void *data, 00253 size_t length, size_t *written, uint_t flags) 00254 { 00255 error_t error; 00256 00257 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED) 00258 //Check whether a secure connection is being used 00259 if(webSocket->tlsContext != NULL) 00260 { 00261 //Use SSL/TLS to transmit data to the client 00262 error = tlsWrite(webSocket->tlsContext, data, length, written, flags); 00263 } 00264 else 00265 #endif 00266 { 00267 //Transmit data 00268 error = socketSend(webSocket->socket, data, length, written, flags); 00269 } 00270 00271 //Return status code 00272 return error; 00273 } 00274 00275 00276 /** 00277 * @brief Receive data using the relevant transport protocol 00278 * @param[in] webSocket Handle to a WebSocket 00279 * @param[out] data Buffer into which received data will be placed 00280 * @param[in] size Maximum number of bytes that can be received 00281 * @param[out] received Number of bytes that have been received 00282 * @param[in] flags Set of flags that influences the behavior of this function 00283 * @return Error code 00284 **/ 00285 00286 error_t webSocketReceiveData(WebSocket *webSocket, void *data, 00287 size_t size, size_t *received, uint_t flags) 00288 { 00289 error_t error; 00290 00291 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED) 00292 //Check whether a secure connection is being used 00293 if(webSocket->tlsContext != NULL) 00294 { 00295 //Use SSL/TLS to receive data from the client 00296 error = tlsRead(webSocket->tlsContext, data, size, received, flags); 00297 } 00298 else 00299 #endif 00300 { 00301 //Receive data 00302 error = socketReceive(webSocket->socket, data, size, received, flags); 00303 } 00304 00305 //Return status code 00306 return error; 00307 } 00308 00309 #endif 00310
Generated on Tue Jul 12 2022 17:10:17 by
