static void save_socket(struct SocketWatcherData *watcher, pubnub_t *pb)
{
    if (watcher->apb_size == watcher->apb_cap) {
        size_t newcap = watcher->apb_cap + 2;
        pubnub_t **npapb = (pubnub_t**)realloc(watcher->apb, sizeof watcher->apb[0] * newcap);
        if (NULL == npapb) {
            return;
        }
        watcher->apb = npapb;
        watcher->apb_cap = newcap;
    }

    FreeRTOS_FD_SET(pb->pal.socket, watcher->xFD_set, eSELECT_ALL);

    watcher->apb[watcher->apb_size] = pb;
    ++watcher->apb_size;
}
static BaseType_t prvSendFile( xHTTPClient *pxClient )
{
size_t xSpace;
size_t xCount;
BaseType_t xRc = 0;

	if( pxClient->bits.bReplySent == pdFALSE )
	{
		pxClient->bits.bReplySent = pdTRUE;

		strcpy( pxClient->pxParent->pcContentsType, pcGetContentsType( pxClient->pcCurrentFilename ) );
		snprintf( pxClient->pxParent->pcExtraContents, sizeof pxClient->pxParent->pcExtraContents,
			"Content-Length: %d\r\n", ( int ) pxClient->xBytesLeft);

		xRc = prvSendReply( pxClient, WEB_REPLY_OK );	/* "Requested file action OK" */
	}

	if( xRc >= 0 ) do
	{
		xSpace = FreeRTOS_tx_space( pxClient->xSocket );

		if( pxClient->xBytesLeft < xSpace )
		{
			xCount = pxClient->xBytesLeft;
		}
		else
		{
			xCount = xSpace;
		}

		if( xCount > 0 )
		{
			if( xCount > sizeof( pxClient->pxParent->pcFileBuffer ) )
			{
				xCount = sizeof( pxClient->pxParent->pcFileBuffer );
			}
			ff_fread( pxClient->pxParent->pcFileBuffer, 1, xCount, pxClient->pxFileHandle );
			pxClient->xBytesLeft -= xCount;

			xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pxParent->pcFileBuffer, xCount, 0 );
			if( xRc < 0 )
			{
				break;
			}
		}
	} while( xCount > 0 );

	if( pxClient->xBytesLeft <= 0 )
	{
		/* Writing is ready, no need for further 'eSELECT_WRITE' events. */
		FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE );
		prvFileClose( pxClient );
	}
	else
	{
		/* Wake up the TCP task as soon as this socket may be written to. */
		FreeRTOS_FD_SET( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE );
	}

	return xRc;
}
Example #3
0
static void prvConnectionListeningTask( void *pvParameters )
{
struct freertos_sockaddr xClient, xBindAddress;
xSocket_t xListeningSocket;

socklen_t xSize = sizeof( xClient );
static const TickType_t xReceiveTimeOut = 0; //portMAX_DELAY;
const BaseType_t xBacklog = 10;
xSocketSet_t xSocketSet;
struct xTCP_SERVER *pxServerList = NULL;
struct xTCP_SERVER *pxIterator;

xWinProperties_t winProps;

	/* Just to prevent compiler warnings. */
	( void ) pvParameters;

	/* Attempt to open the socket. */
	xListeningSocket = FreeRTOS_socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
	configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );

	/* Set a time out so accept() will just wait for a connection. */
	FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );

	memset(&winProps, '\0', sizeof( winProps ) );
	// Size in units of MSS
	winProps.lTxBufSize   = 1 * 1460;//1000;
	winProps.lTxWinSize   = 2;

	winProps.lRxBufSize   = 2 * 1460;
	winProps.lRxWinSize   =  2;

	FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &winProps, sizeof( winProps ) );

	/* The strange casting is to remove compiler errors. */
	xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL;
	xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port );

	/* Bind the socket to the port that the client task will send to, then
	listen for incoming connections. */
	while( FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ) != 0 );
	FreeRTOS_listen( xListeningSocket, xBacklog );
	lastTickTime = xTaskGetTickCount ();

	pxServerList = NULL;

	xSocketSet = FreeRTOS_createsocketset( );
	configASSERT( xSocketSet != NULL );
	FreeRTOS_FD_SET( xListeningSocket, xSocketSet, eSELECT_READ );

	for( ;; )
	{
		TickType_t xMask = FreeRTOS_select( xSocketSet, 3000 );

		if( FreeRTOS_FD_ISSET( xListeningSocket, xSocketSet ) )
		{
			xSocket_t xNewSocket;

			xNewSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize );
			if ( xNewSocket && xNewSocket != FREERTOS_INVALID_SOCKET )
			{
				xTcpServer_t *pxServer;

				FreeRTOS_debug_printf( ( "prvConnectionListeningTask: new connection %xip:%u\n",
					FreeRTOS_ntohl( xClient.sin_addr ), FreeRTOS_ntohs( xClient.sin_port ) ) );

				pxServer = (xTcpServer_t *)pvPortMalloc( sizeof( *pxServer ) );
				memset( pxServer, '\0', sizeof( *pxServer ));

				pxServer->xSocket = xNewSocket;
				FreeRTOS_FD_SET( xNewSocket, xSocketSet, eSELECT_READ | eSELECT_EXCEPT );
				if( pxServerList == NULL )
				{
					/* This is the first server */
					pxServerList = pxServer;
				}
				else
				{
					/* Attach it to the end of the list */
					for( pxIterator = pxServerList; pxIterator->pxNext != NULL; pxIterator = pxIterator->pxNext )
					{
					}
					pxIterator->pxNext = pxServer;
				}
				prvTcpInit( pxServer );
			}
		}
		{
			xTcpServer_t *pxThisServer = NULL;

			for( pxIterator = pxServerList; pxIterator != NULL;  )
			{
				BaseType_t rc;
				pxThisServer = pxIterator;
				/* Move to the next one before the current gets deleted */
				pxIterator = pxIterator->pxNext;

				if( FreeRTOS_FD_ISSET( pxThisServer->xSocket, xSocketSet )  == 0 )
				{
					continue;
				}

				rc = prvTcpWork( pxThisServer );

				if( rc < 0)
				{
					FreeRTOS_FD_CLR( pxThisServer->xSocket, xSocketSet, eSELECT_ALL );

					if( pxServerList = pxThisServer )
					{
						pxServerList = pxThisServer->pxNext;
					}
					else
					{
						struct xTCP_SERVER *pxOther;
						for( pxOther = pxServerList; pxOther->pxNext != NULL; pxOther = pxOther->pxNext )
						{
							if( pxOther->pxNext == pxThisServer )
							{
								pxOther->pxNext == pxThisServer->pxNext;
								break;
							}
						}
					}
					/* Close the socket and free the space */
					prvTcpClose( pxThisServer );
				} else
				{
					pxThisServer->bHasSendRequest = prvTcpHasSendData( pxThisServer );
					if( pxThisServer->bHasSendRequest )
						FreeRTOS_FD_SET( pxThisServer->xSocket, xSocketSet, eSELECT_WRITE );
					else
						FreeRTOS_FD_CLR( pxThisServer->xSocket, xSocketSet, eSELECT_WRITE );
					//FreeRTOS_debug_printf( ( "SET_FD WRITE %d\n", pxServerFound->bHasSendRequest != 0 ) );
				}
			}
		}
		if( ( xTaskGetTickCount () - lastTickTime ) > 30000 )
		{
			lastTickTime = xTaskGetTickCount ();
			//plusPrintf( "ListeningTask %ld,%ld tasks\n", xTaskCount, xConfirmedCount );
		}
	}
}
Example #4
0
static void prvMultipleSocketRxTask( void *pvParameters )
{
xSocketSet_t xFD_Set;
xSocket_t xSocket;
struct freertos_sockaddr xAddress;
uint32_t xClientLength = sizeof( struct freertos_sockaddr ), ulFirstRxPortNumber, x;
uint32_t ulReceivedValue = 0, ulExpectedValue = 0UL, ulReceivedCount[ selNUMBER_OF_SOCKETS ] = { 0 };
int32_t lBytes;
const TickType_t xRxBlockTime = 0;

	/* The number of the port the first Rx socket will be bound to is passed in
	as the task parameter.  Other port numbers used are consecutive from this. */
	ulFirstRxPortNumber = ( uint32_t ) pvParameters;

	/* Create the set of sockets that will be passed into FreeRTOS_select(). */
	xFD_Set = FreeRTOS_CreateSocketSet( selSELECT_QUEUE_SIZE );

	for( x = 0; x < selNUMBER_OF_SOCKETS; x++ )
	{
		/* Create the next Rx socket. */
		xRxSockets[ x ] = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
		configASSERT( xRxSockets[ x ] );

		/* Bind to the next port number. */
		xAddress.sin_port = FreeRTOS_htons( ( uint16_t ) ( ulFirstRxPortNumber + x ) );
		FreeRTOS_bind( xRxSockets[ x ], &xAddress, sizeof( struct freertos_sockaddr ) );

		/* There should always be data available on the socket returned from
		FreeRTOS_select() so blocking on a read should not be necessary. */
		FreeRTOS_setsockopt( xRxSockets[ x ], 0, FREERTOS_SO_RCVTIMEO, &xRxBlockTime, sizeof( xRxBlockTime ) );

		/* Add the created socket to the set. */
		FreeRTOS_FD_SET( xRxSockets[ x ], xFD_Set );
	}

	for( ;; )
	{
		/* Wait for a socket from the set to become available for reading. */
		xSocket = FreeRTOS_select( xFD_Set, portMAX_DELAY );

		/* xSocket should never be NULL because FreeRTOS_select() was called
		with an indefinite delay (assuming INCLUDE_vTaskSuspend is set to 1). */
		configASSERT( xSocket );

		lBytes = FreeRTOS_recvfrom( xSocket, &( ulReceivedValue ), sizeof( uint32_t ), 0, &xAddress, &xClientLength );

		/* It is possible that the first value received will not be zero
		because the first few transmitted packets may have been dropped to
		send an ARP and then wait the ARP reply. */
		if( ulExpectedValue == 0 )
		{
			if( ulExpectedValue != ulReceivedValue )
			{
				/* Correct for packets lost to ARP traffic. */
				ulExpectedValue = ulReceivedValue;
			}
		}

		/* Data should always be available even though the block time was set
		to zero because the socket was returned from FreeRTOS_select(). */
		configASSERT( lBytes == 4 );
		configASSERT( ulReceivedValue == ulExpectedValue );

		ulExpectedValue++;

		/* Keep a record of the number of times each socket has been used so it
		can be verified (using the debugger) that they all get used. */
		for( x= 0; x < selNUMBER_OF_SOCKETS; x++ )
		{
			if( xSocket == xRxSockets[ x ] )
			{
				( ulReceivedCount[ x ] )++;
				break;
			}
		}
	}
}
Example #5
0
static void prvMultipleSocketRxTask( void *pvParameters )
{
xSocketSet_t xFD_Set;
xSocket_t xSocket;
struct freertos_sockaddr xAddress;
uint32_t xClientLength = sizeof( struct freertos_sockaddr ), ulFirstRxPortNumber, x;
uint32_t ulReceivedValue = 0, ulCount;
uint8_t ucReceivedValues[ selMAX_TX_VALUE ]; /* If the array position is pdTRUE then the corresponding value has been received. */
int32_t lBytes;
const TickType_t xRxBlockTime = 0;
BaseType_t xResult;

	/* The number of the port the first Rx socket will be bound to is passed in
	as the task parameter.  Other port numbers used are consecutive from this. */
	ulFirstRxPortNumber = ( uint32_t ) pvParameters;

	/* Create the set for sockets that will be passed into FreeRTOS_select(). */
	xFD_Set = FreeRTOS_CreateSocketSet();

	/* Create the sockets and add them to the set. */
	for( x = 0; x < selNUMBER_OF_SOCKETS; x++ )
	{
		/* Create the next Rx socket. */
		xRxSockets[ x ] = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
		configASSERT( xRxSockets[ x ] != FREERTOS_INVALID_SOCKET );

		/* Bind to the next port number. */
		xAddress.sin_port = FreeRTOS_htons( ( uint16_t ) ( ulFirstRxPortNumber + x ) );
		FreeRTOS_bind( xRxSockets[ x ], &xAddress, sizeof( struct freertos_sockaddr ) );

		/* There should always be data available after FreeRTOS_select() so
		blocking on a read should not be necessary. */
		FreeRTOS_setsockopt( xRxSockets[ x ], 0, FREERTOS_SO_RCVTIMEO, &xRxBlockTime, sizeof( xRxBlockTime ) );

		/* Add the created socket to the set. */
		FreeRTOS_FD_SET( xRxSockets[ x ], xFD_Set, eSELECT_ALL );
	}

	for( ;; )
	{
		/* No values have yet been received so set each array position to
		pdFALSE.  Each expected Rx value has a corresponding array position. */
		memset( ( void * ) ucReceivedValues, pdFALSE, sizeof( ucReceivedValues ) );

		/* Wait for the other task to resume this task - indicating that it is
		about to start sending. */
		vTaskSuspend( NULL );

		/* Expect to receive selMAX_TX_VALUE values. */
		ulCount = 0;

		while( ulCount < selMAX_TX_VALUE )
		{
			/* Wait for a socket from the set to become available for
			reading. */
			xResult = FreeRTOS_select( xFD_Set, xReceiveBlockTime );

			if( xResult != 0 )
			{
				/* See which sockets have data waiting to be read. */
				for( x = 0; x < selNUMBER_OF_SOCKETS; x++ )
				{
					xSocket = xRxSockets[ x ];

					/* Find the expected value for this socket */
					if( FreeRTOS_FD_ISSET( xSocket, xFD_Set ) != 0 )
					{
						while( ( lBytes = FreeRTOS_recvfrom( xSocket, &( ulReceivedValue ), sizeof( uint32_t ), 0, &xAddress, &xClientLength ) ) > 0 )
						{
							/* Received another message. */
							ulCount++;

							/* It is always expected that the read will pass. */
							configASSERT( ( size_t ) lBytes == ( sizeof( uint32_t ) ) );

							/* Don't expect to receive anything greater than
							selMAX_TX_VALUE - 1. */
							configASSERT( ulReceivedValue < selMAX_TX_VALUE );

							/* Don't expect to receive any value twice. */
							configASSERT( ucReceivedValues[ ulReceivedValue ] != pdTRUE );
							if( ucReceivedValues[ ulReceivedValue ] != pdTRUE )
							{
								/* Mark the value as received by setting its
								index in the received array to pdTRUE. */
								ucReceivedValues[ ulReceivedValue ] = pdTRUE;
							}
							else
							{
								ulErrorOccurred = pdTRUE;
							}
						}
					}
				}
			}
			else
			{
				/* No value was received in time. */
				break;
			}
		}

		/* Were all values received? */
		if( ulCount == selMAX_TX_VALUE )
		{
			/* Check all selMAX_TX_VALUE values are present and correct
			before starting a new cycle.  It is valid for a few values at
			the beginning of the array to be missing as they may have been
			dropped for ARP messages, so start a few indexes in. */
			for( ulCount = 4; ulCount < selMAX_TX_VALUE; ulCount++ )
			{
				configASSERT( ucReceivedValues[ ulCount ] == pdTRUE );

				if( ucReceivedValues[ ulCount ] != pdTRUE )
				{
					/* The value corresponding to this array position was
					never received.  In a real application UDP is not
					reliable, but in this tightly controlled test it is
					unusual for a packet to be dropped. */
					ulErrorOccurred = pdTRUE;
				}
			}

			ulRxCycles++;
		}
		else
		{
			/* Just for viewing in the debugger. */
			ulFailedRxCycles++;
		}
	}
}