int pbntf_init(void)
{
    m_watcher.mutw = xSemaphoreCreateRecursiveMutex();
    if (NULL == m_watcher.mutw) {
        return -1;
    }
    
    m_watcher.xFD_set = FreeRTOS_CreateSocketSet();
    if (NULL == m_watcher.xFD_set) {
        vSemaphoreDelete(m_watcher.mutw);
        return -1;
    }
    if (pdPASS != xTaskCreate(
        socket_watcher_task, 
        "Pubnub socket watcher", 
        SOCKET_WATCHER_STACK_DEPTH, 
        &m_watcher, 
        PUBNUB_TASK_PRIORITY, 
        &m_watcher.task
        )) {
        vSemaphoreDelete(m_watcher.mutw);
        FreeRTOS_DeleteSocketSet(m_watcher.xFD_set);
        return -1;
    }
    return 0;
}
Beispiel #2
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;
			}
		}
	}
}
Beispiel #3
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++;
		}
	}
}