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.
discard.c
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
Generated on Tue Jul 12 2022 17:10:13 by
1.7.2