Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers web_socket_transport.c Source File

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