Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers discard.c Source File

discard.c

Go to the documentation of this file.
00001 /**
00002  * @file discard.c
00003  * @brief Discard protocol
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  * @section Description
00026  *
00027  * The discard service is a useful debugging and measurement tool. The service
00028  * simply throws away any data it receives. Refer to RFC 863 for complete details
00029  *
00030  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00031  * @version 1.7.6
00032  **/
00033 
00034 //Switch to the appropriate trace level
00035 #define TRACE_LEVEL STD_SERVICES_TRACE_LEVEL
00036 
00037 //Dependencies
00038 #include "core/net.h"
00039 #include "std_services/discard.h"
00040 #include "debug.h"
00041 
00042 
00043 /**
00044  * @brief Start TCP discard service
00045  * @return Error code
00046  **/
00047 
00048 error_t tcpDiscardStart(void)
00049 {
00050    error_t error;
00051    Socket *socket;
00052    OsTask *task;
00053 
00054    //Debug message
00055    TRACE_INFO("Starting TCP discard service...\r\n");
00056 
00057    //Open a TCP socket
00058    socket = socketOpen(SOCKET_TYPE_STREAM, SOCKET_IP_PROTO_TCP);
00059    //Failed to open socket?
00060    if(socket == NULL)
00061       return ERROR_OPEN_FAILED;
00062 
00063    //Start of exception handling block
00064    do
00065    {
00066       //Bind the newly created socket to port 9
00067       error = socketBind(socket, &IP_ADDR_ANY, DISCARD_PORT);
00068       //Failed to bind the socket to the desired port?
00069       if(error)
00070          break;
00071 
00072       //Place the socket into listening mode
00073       error = socketListen(socket, 0);
00074       //Any error to report?
00075       if(error)
00076          break;
00077 
00078       //Create a task to handle incoming connection requests
00079       task = osCreateTask("TCP Discard Listener", tcpDiscardListenerTask,
00080          socket, DISCARD_SERVICE_STACK_SIZE, DISCARD_SERVICE_PRIORITY);
00081 
00082       //Unable to create the task?
00083       if(task == OS_INVALID_HANDLE)
00084       {
00085          //Report an error to the calling function
00086          error = ERROR_OUT_OF_RESOURCES;
00087          break;
00088       }
00089 
00090       //End of exception handling block
00091    } while(0);
00092 
00093    //Any error to report?
00094    if(error)
00095    {
00096       //Clean up side effects...
00097       socketClose(socket);
00098    }
00099 
00100    //Return status code
00101    return error;
00102 }
00103 
00104 
00105 /**
00106  * @brief Task handling connection requests
00107  * @param[in] param Pointer to the discard service context
00108  **/
00109 
00110 void tcpDiscardListenerTask(void *param)
00111 {
00112    error_t error;
00113    uint16_t clientPort;
00114    IpAddr clientIpAddr;
00115    Socket *serverSocket;
00116    Socket *clientSocket;
00117    DiscardServiceContext *context;
00118    OsTask *task;
00119 
00120    //Point to the listening socket
00121    serverSocket = (Socket *) param;
00122 
00123    //Main loop
00124    while(1)
00125    {
00126       //Accept an incoming connection
00127       clientSocket = socketAccept(serverSocket, &clientIpAddr, &clientPort);
00128       //Check whether a valid connection request has been received
00129       if(!clientSocket) continue;
00130 
00131       //Debug message
00132       TRACE_INFO("Discard service: connection established with client %s port %" PRIu16 "\r\n",
00133          ipAddrToString(&clientIpAddr, NULL), clientPort);
00134 
00135       //Adjust timeout
00136       error = socketSetTimeout(clientSocket, DISCARD_TIMEOUT);
00137 
00138       //Any error to report?
00139       if(error)
00140       {
00141          //Close socket
00142          socketClose(clientSocket);
00143          //Wait for an incoming connection attempt
00144          continue;
00145       }
00146 
00147       //Allocate resources for the new connection
00148       context = osAllocMem(sizeof(DiscardServiceContext));
00149 
00150       //Failed to allocate memory?
00151       if(context == NULL)
00152       {
00153          //Close socket
00154          socketClose(clientSocket);
00155          //Wait for an incoming connection attempt
00156          continue;
00157       }
00158 
00159       //Record the handle of the newly created socket
00160       context->socket = clientSocket;
00161 
00162       //Create a task to service the current connection
00163       task = osCreateTask("TCP Discard Connection", tcpDiscardConnectionTask,
00164          context, DISCARD_SERVICE_STACK_SIZE, DISCARD_SERVICE_PRIORITY);
00165 
00166       //Did we encounter an error?
00167       if(task == OS_INVALID_HANDLE)
00168       {
00169          //Close socket
00170          socketClose(clientSocket);
00171          //Release resources
00172          osFreeMem(context);
00173       }
00174    }
00175 }
00176 
00177 
00178 /**
00179  * @brief TCP discard service implementation
00180  * @param[in] param Pointer to the discard service context
00181  **/
00182 
00183 void tcpDiscardConnectionTask(void *param)
00184 {
00185    error_t error;
00186    size_t n;
00187    size_t byteCount;
00188    systime_t startTime;
00189    systime_t duration;
00190    DiscardServiceContext *context;
00191 
00192    //Get a pointer to the context
00193    context = (DiscardServiceContext *) param;
00194    //Get current time
00195    startTime = osGetSystemTime();
00196 
00197    //Total number of bytes received
00198    byteCount = 0;
00199 
00200    //Main loop
00201    while(1)
00202    {
00203       //Throw away any received datagram...
00204       error = socketReceive(context->socket, context->buffer, DISCARD_BUFFER_SIZE, &n, 0);
00205       //Any error to report?
00206       if(error)
00207          break;
00208 
00209       //Total number of bytes received
00210       byteCount += n;
00211    }
00212 
00213    //Graceful shutdown
00214    socketShutdown(context->socket, SOCKET_SD_BOTH);
00215    //Compute total duration
00216    duration = osGetSystemTime() - startTime;
00217    //Avoid division by zero...
00218    if(!duration) duration = 1;
00219 
00220    //Debug message
00221    TRACE_INFO("Discard service: %" PRIuSIZE " bytes "
00222       "received in %" PRIu32 " ms (%" PRIu32 " kBps, %" PRIu32 " kbps)\r\n",
00223       byteCount, duration, byteCount / duration, (byteCount * 8) / duration);
00224 
00225    //Close socket
00226    socketClose(context->socket);
00227    //Release previously allocated memory
00228    osFreeMem(context);
00229 
00230    //Kill ourselves
00231    osDeleteTask(NULL);
00232 }
00233 
00234 
00235 /**
00236  * @brief Start UDP discard service
00237  * @return Error code
00238  **/
00239 
00240 error_t udpDiscardStart(void)
00241 {
00242    error_t error;
00243    DiscardServiceContext *context;
00244    OsTask *task;
00245 
00246    //Debug message
00247    TRACE_INFO("Starting UDP discard service...\r\n");
00248 
00249    //Allocate a memory block to hold the context
00250    context = osAllocMem(sizeof(DiscardServiceContext));
00251    //Failed to allocate memory?
00252    if(context == NULL)
00253       return ERROR_OUT_OF_MEMORY;
00254 
00255    //Start of exception handling block
00256    do
00257    {
00258       //Open a UDP socket
00259       context->socket = socketOpen(SOCKET_TYPE_DGRAM, SOCKET_IP_PROTO_UDP);
00260 
00261       //Failed to open socket?
00262       if(!context->socket)
00263       {
00264          //Report an error
00265          error = ERROR_OPEN_FAILED;
00266          //Exit immediately
00267          break;
00268       }
00269 
00270       //The server listens for incoming datagrams on port 9
00271       error = socketBind(context->socket, &IP_ADDR_ANY, DISCARD_PORT);
00272       //Unable to bind the socket to the desired port?
00273       if(error)
00274          break;
00275 
00276       //Create a task to handle incoming datagrams
00277       task = osCreateTask("UDP Discard", udpDiscardTask,
00278          context, DISCARD_SERVICE_STACK_SIZE, DISCARD_SERVICE_PRIORITY);
00279 
00280       //Unable to create the task?
00281       if(task == OS_INVALID_HANDLE)
00282       {
00283          //Report an error to the calling function
00284          error = ERROR_OUT_OF_RESOURCES;
00285          break;
00286       }
00287 
00288       //End of exception handling block
00289    } while(0);
00290 
00291    //Any error to report?
00292    if(error)
00293    {
00294       //Clean up side effects...
00295       socketClose(context->socket);
00296       osFreeMem(context);
00297    }
00298 
00299    //Return status code
00300    return error;
00301 }
00302 
00303 
00304 /**
00305  * @brief UDP discard service implementation
00306  * @param[in] param Pointer to the discard service context
00307  **/
00308 
00309 void udpDiscardTask(void *param)
00310 {
00311    error_t error;
00312    size_t length;
00313    uint16_t port;
00314    IpAddr ipAddr;
00315    DiscardServiceContext *context;
00316 
00317    //Get a pointer to the context
00318    context = (DiscardServiceContext *) param;
00319 
00320    //Main loop
00321    while(1)
00322    {
00323       //Wait for an incoming datagram
00324       error = socketReceiveFrom(context->socket, &ipAddr, &port,
00325          context->buffer, DISCARD_BUFFER_SIZE, &length, 0);
00326 
00327       //Any datagram received?
00328       if(!error)
00329       {
00330          //Debug message
00331          TRACE_INFO("Discard service: %" PRIuSIZE " bytes received from %s port %" PRIu16 "\r\n",
00332             length, ipAddrToString(&ipAddr, NULL), port);
00333 
00334          //Throw away any received datagram...
00335       }
00336    }
00337 }
00338