static BaseType_t prvSendReply( xHTTPClient *pxClient, BaseType_t xCode )
{
struct xTCP_SERVER *pxParent = pxClient->pxParent;
BaseType_t xRc;

	// A normal command reply on the main socket (port 21)
	char *pcBuffer = pxParent->pcFileBuffer;

	xRc = snprintf( pcBuffer, sizeof( pxParent->pcFileBuffer ),
		"HTTP/1.1 %d %s\r\n"
#if	USE_HTML_CHUNKS
		"Transfer-Encoding: chunked\r\n"
#endif
		"Content-Type: %s\r\n"
		"Connection: keep-alive\r\n"
		"%s\r\n",
		( int ) xCode,
		webCodename (xCode),
		pxParent->pcContentsType[0] ? pxParent->pcContentsType : "text/html",
		pxParent->pcExtraContents );

	pxParent->pcContentsType[0] = '\0';
	pxParent->pcExtraContents[0] = '\0';

	xRc = FreeRTOS_send( pxClient->xSocket, ( const void * ) pcBuffer, xRc, 0 );
	pxClient->bits.bReplySent = pdTRUE;

	return xRc;
}
int FreeRTOS_write(Network* n, unsigned char* buffer, int len,
                   uint32_t timeout_ms) {
    portTickType xTicksToWait = timeout_ms / portTICK_RATE_MS; /* convert milliseconds to ticks */
    xTimeOutType xTimeOut;
    int sentLen = 0;

    vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */

    FreeRTOS_setsockopt(n->my_socket, SOL_SOCKET, FREERTOS_SO_RCVTIMEO,
                        &timeout_ms, sizeof(timeout_ms));

    do {
        int rc = 0;
        rc = FreeRTOS_send(n->my_socket, buffer + sentLen, len - sentLen, 0);
        if (rc > 0)
            sentLen += rc;
        else if (rc < 0) {
            sentLen = rc;
            break;
        }
    } while (sentLen < len
             && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);

    return sentLen;
}
Beispiel #3
0
static BaseType_t prvTcpWork( xTcpServer_t *pxTcpServer )
{
BaseType_t lBytes, lReturned, lMayWrite;

	lMayWrite = FreeRTOS_maywrite( pxTcpServer->xSocket );
	if( lMayWrite < 0 )
		return lMayWrite;
	while( lMayWrite > 0 )
	{
		lReturned = prvTcpSend( pxTcpServer );
		if( lReturned < 0 )
			return lReturned;
		if( lReturned == 0 )
			break;
		lMayWrite = FreeRTOS_maywrite( pxTcpServer->xSocket );
		if( lMayWrite < 0 )
			return lMayWrite;
	}
	for( ; ; )
	{
		/* Zero out the receive array so there is NULL at the end of the string
		when it is printed out. */
		memset( cReceivedString, 0x00, sizeof( cReceivedString ) );

		/* Receive data on the socket. */
		lBytes = FreeRTOS_recv( pxTcpServer->xSocket, cReceivedString, sizeof( cReceivedString ), 0 );
		if( lBytes <= 0 )
				return lBytes;
		/* Return the received characters. */
		if( lMayWrite > 0 && sbGetSize( pxTcpServer->pxSendData ) == 0 )
		{
			/* The cirular buffer is empty, send the received data directly */
			lReturned = FreeRTOS_send( pxTcpServer->xSocket, cReceivedString, lBytes, 0 );
			if( lReturned < 0 )
			{
				return -1;
			}
			if( lBytes > lReturned )
			{
				/* Not all dta could be delivered, save them for later
					* FD_SET( eSELECT_WRITE ) will be called */
				sbAdd( pxTcpServer->pxSendData, 0, cReceivedString + lReturned, lBytes - lReturned );
			}
			lMayWrite = FreeRTOS_maywrite( pxTcpServer->xSocket );
			if( lMayWrite < 0 )
				return lMayWrite;
		} else
		{
			sbAdd( pxTcpServer->pxSendData, 0, cReceivedString, lBytes );
		}
	}
}
Beispiel #4
0
static BaseType_t prvTcpSend( xTcpServer_t *pxTcpServer )
{
BaseType_t lBytes, lReturned, xReturn = 0;

	lBytes = sbGet( pxTcpServer->pxSendData, 0, cReceivedString, sizeof( cReceivedString ), pdTRUE );
	if( lBytes )
	{
		/* Send as much as possible, non-blocking */
		lReturned = FreeRTOS_send( pxTcpServer->xSocket, cReceivedString, lBytes, 0 );
		if( lReturned > 0 )
		{
			xReturn = sbGet( pxTcpServer->pxSendData, 0, NULL, lReturned, pdFALSE );
		}
	}
	return xReturn;
}
Beispiel #5
0
void z80BiosConsoleIO(trapargs_t *reg)
{
	char *caller = (char*)(*(uint16_t*)&reg->trapret + ( reg->mbase << 16));
	char dir = caller[1];
	char c = reg->af >> 8;
	
	
	if(dir)	// input
		switch((port_CONIO_t) caller[2])
		{
			case CONSTA:	// console status port
				if(xQueuePeek(cpminq,&c,0) == pdTRUE)
						reg->af |= 0xFF00;
					else
						reg->af &= ~0xFF00;
				break;

			case CONDAT:	// console data port
				if(xQueueReceive(cpminq,&c,portMAX_DELAY) == pdTRUE)
						reg->af = reg->af & ~0xFF00 | (c << 8);
					else
						reg->af &= ~0xFF00;
				break;
				
			case PRTSTA:	// printer status port
			case PRTDAT:	// printer data port
			case AUXDAT:	// auxiliary data port
			default:
				reg->af &= ~0xFF00;
				break;
		}
	else	// output
		switch((port_CONIO_t) caller[2])
		{
			case CONDAT:	// console data port
				FreeRTOS_send(xConnectedSocket,&c,1,0);
				break;
			case CONSTA:	// console status port
			case PRTSTA:	// printer status port
			case PRTDAT:	// printer data port
			case AUXDAT:	// auxiliary data port
			default:
				break;
		};
}
Beispiel #6
0
void prvTCPCpmIOTask( void *ram )
{
	BaseType_t iosize;
	char cRxedChar, cInputIndex = 0;
	struct freertos_sockaddr xClient;
	Socket_t xListeningSocket;
	socklen_t xSize = sizeof( xClient );

	cpminq = xQueueCreate(81, sizeof( CHAR));
	
	while(FreeRTOS_IsNetworkUp() == pdFALSE)
		vTaskDelay(3000);
 

	/* Create the socket. */
	xSocketRDisk = FreeRTOS_socket( FREERTOS_AF_INET,
                              FREERTOS_SOCK_DGRAM,
                              FREERTOS_IPPROTO_UDP );

 
   /* Check the socket was created. */
   configASSERT( xSocketRDisk != FREERTOS_INVALID_SOCKET );
	
	for( ;; )
	{
		/* Attempt to open the socket.  The port number is passed in the task
		parameter.  The strange casting is to remove compiler warnings on 32-bit
		machines.  NOTE:  The FREERTOS_SO_REUSE_LISTEN_SOCKET option is used,
		so the listening and connecting socket are the same - meaning only one
		connection will be accepted at a time, and that xListeningSocket must
		be created on each iteration. */
		xListeningSocket = prvOpenTCPServerSocket( RDSK_PORT);

		/* Nothing for this task to do if the socket cannot be created. */
		if( xListeningSocket == FREERTOS_INVALID_SOCKET )
		{
			vTaskDelete( NULL );
		}

		/* Wait for an incoming connection. */
		xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize );

		/* The FREERTOS_SO_REUSE_LISTEN_SOCKET option is set, so the
		connected and listening socket should be the same socket. */
		configASSERT( xConnectedSocket == xListeningSocket );
		xRDiskAddress.sin_addr = xClient.sin_addr;
		xRDiskAddress.sin_port = FreeRTOS_htons( RDSK_PORT );

		
		iosize = xTaskCreate( CPM22Task, "CPM22Task", configMINIMAL_STACK_SIZE*5, ram, PRIO_CPM22,&thcpm);
		if(iosize != pdPASS)
		{
			prvGracefulShutdown( xListeningSocket );
			vTaskDelete( NULL );
		}
		
		/* Send the welcome message. */
		iosize = FreeRTOS_send( xConnectedSocket,  ( void * ) pcWelcomeMessage,  strlen( pcWelcomeMessage ), 0 );
		xQueueReset(cpminq);
		
		
		/* Process the socket as long as it remains connected. */
		while( iosize >= 0 )
		{
			char c;
			/* Receive data on the socket. */
			iosize = FreeRTOS_recv( xConnectedSocket, &c, 1, 0 );
			
			if( iosize >= 0 )
			{
				xQueueSend(cpminq,&c,0);		
			}
			else
			{
				/* Socket closed? */
				break;
			}
		}
		/* Close the socket correctly. */
		prvGracefulShutdown( xListeningSocket );
	}
}
Beispiel #7
0
static void prvServerConnectionInstance( void *pvParameters )
{
int32_t lBytes, lSent, lTotalSent;
uint8_t cReceivedString[ ipconfigTCP_MSS ];
xSocket_t xConnectedSocket;
static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 );
static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 5000 );
TickType_t xTimeOnShutdown;

	ulConnectionCount++;
	xConnectedSocket = ( xSocket_t ) pvParameters;
	FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
	FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xReceiveTimeOut ) );

	for( ;; )
	{
		/* Zero out the receive array so there is NULL at the end of the string
		when it is printed out. */
		memset( cReceivedString, 0x00, sizeof( cReceivedString ) );

		/* Receive data on the socket. */
		lBytes = FreeRTOS_recv( xConnectedSocket, cReceivedString, sizeof( cReceivedString ), 0 );

		/* If data was received, echo it back. */
		if( lBytes >= 0 )
		{
			lSent = 0;
			lTotalSent = 0;

			/* Call send() until all the data has been sent. */
			while( ( lSent >= 0 ) && ( lTotalSent < lBytes ) )
			{
				lSent = FreeRTOS_send( xConnectedSocket, cReceivedString, lBytes - lTotalSent, 0 );
				lTotalSent += lSent;
			}

			if( lSent < 0 )
			{
				/* Socket closed? */
				break;
			}
		}
		else
		{
			/* Socket closed? */
			break;
		}
	}

	/* Initiate a shutdown in case it has not already been initiated. */
	FreeRTOS_shutdown( xConnectedSocket, FREERTOS_SHUT_RDWR );

	/* Wait for the shutdown to take effect, indicated by FreeRTOS_recv()
	returning an error. */
	xTimeOnShutdown = xTaskGetTickCount();
	do
	{
		if( FreeRTOS_recv( xConnectedSocket, cReceivedString, ipconfigTCP_MSS, 0 ) < 0 )
		{
			break;
		}
	} while( ( xTaskGetTickCount() - xTimeOnShutdown ) < tcpechoSHUTDOWN_DELAY );

	/* Finished with the socket and the task. */
	FreeRTOS_closesocket( xConnectedSocket );
	vTaskDelete( NULL );
}
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;
}
static void prvEchoClientTask( void *pvParameters )
{
Socket_t xSocket;
struct freertos_sockaddr xEchoServerAddress;
int32_t lLoopCount = 0UL;
const int32_t lMaxLoopCount = 1;
volatile uint32_t ulTxCount = 0UL;
BaseType_t xReceivedBytes, xReturned, xInstance;
BaseType_t lTransmitted, lStringLength;
char *pcTransmittedString, *pcReceivedString;
WinProperties_t xWinProps;
TickType_t xTimeOnEntering;

	/* Fill in the buffer and window sizes that will be used by the socket. */
	xWinProps.lTxBufSize = 6 * ipconfigTCP_MSS;
	xWinProps.lTxWinSize = 3;
	xWinProps.lRxBufSize = 6 * ipconfigTCP_MSS;
	xWinProps.lRxWinSize = 3;

	/* This task can be created a number of times.  Each instance is numbered
	to enable each instance to use a different Rx and Tx buffer.  The number is
	passed in as the task's parameter. */
	xInstance = ( BaseType_t ) pvParameters;

	/* Point to the buffers to be used by this instance of this task. */
	pcTransmittedString = &( cTxBuffers[ xInstance ][ 0 ] );
	pcReceivedString = &( cRxBuffers[ xInstance ][ 0 ] );

	/* Echo requests are sent to the echo server.  The address of the echo
	server is configured by the constants configECHO_SERVER_ADDR0 to
	configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */
	xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT );
	xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0,
															configECHO_SERVER_ADDR1,
															configECHO_SERVER_ADDR2,
															configECHO_SERVER_ADDR3 );

	for( ;; )
	{
		/* Create a TCP socket. */
		xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
		configASSERT( xSocket != FREERTOS_INVALID_SOCKET );

		/* Set a time out so a missing reply does not cause the task to block
		indefinitely. */
		FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
		FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) );

		/* Set the window and buffer sizes. */
		FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps,	sizeof( xWinProps ) );

		/* Connect to the echo server. */
		if( FreeRTOS_connect( xSocket, &xEchoServerAddress, sizeof( xEchoServerAddress ) ) == 0 )
		{
			ulConnections[ xInstance ]++;

			/* Send a number of echo requests. */
			for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ )
			{
				/* Create the string that is sent to the echo server. */
				lStringLength = prvCreateTxData( pcTransmittedString, echoBUFFER_SIZES );

				/* Add in some unique text at the front of the string. */
				sprintf( pcTransmittedString, "TxRx message number %u", ulTxCount );
				ulTxCount++;

				/* Send the string to the socket. */
				lTransmitted = FreeRTOS_send(	xSocket,						/* The socket being sent to. */
												( void * ) pcTransmittedString,	/* The data being sent. */
												lStringLength,					/* The length of the data being sent. */
												0 );							/* No flags. */

				if( lTransmitted < 0 )
				{
					/* Error? */
					break;
				}

				/* Clear the buffer into which the echoed string will be
				placed. */
				memset( ( void * ) pcReceivedString, 0x00, echoBUFFER_SIZES );
				xReceivedBytes = 0;

				/* Receive data echoed back to the socket. */
				while( xReceivedBytes < lTransmitted )
				{
					xReturned = FreeRTOS_recv( xSocket,								/* The socket being received from. */
											&( pcReceivedString[ xReceivedBytes ] ),/* The buffer into which the received data will be written. */
											 lStringLength - xReceivedBytes,		/* The size of the buffer provided to receive the data. */
											 0 );									/* No flags. */

					if( xReturned < 0 )
					{
						/* Error occurred.  Latch it so it can be detected
						below. */
						xReceivedBytes = xReturned;
						break;
					}
					else if( xReturned == 0 )
					{
						/* Timed out. */
						break;
					}
					else
					{
						/* Keep a count of the bytes received so far. */
						xReceivedBytes += xReturned;
					}
				}

				/* If an error occurred it will be latched in xReceivedBytes,
				otherwise xReceived bytes will be just that - the number of
				bytes received from the echo server. */
				if( xReceivedBytes > 0 )
				{
					/* Compare the transmitted string to the received string. */
					configASSERT( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 );
					if( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 )
					{
						/* The echo reply was received without error. */
						ulTxRxCycles[ xInstance ]++;
					}
					else
					{
						/* The received string did not match the transmitted
						string. */
						ulTxRxFailures[ xInstance ]++;
						break;
					}
				}
				else if( xReceivedBytes < 0 )
				{
					/* FreeRTOS_recv() returned an error. */
					break;
				}
				else
				{
					/* Timed out without receiving anything? */
					break;
				}
			}

			/* Finished using the connected socket, initiate a graceful close:
			FIN, FIN+ACK, ACK. */
			FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );

			/* Expect FreeRTOS_recv() to return an error once the shutdown is
			complete. */
			xTimeOnEntering = xTaskGetTickCount();
			do
			{
				xReturned = FreeRTOS_recv( xSocket,	/* The socket being received from. */
					&( pcReceivedString[ 0 ] ),		/* The buffer into which the received data will be written. */
					echoBUFFER_SIZES,				/* The size of the buffer provided to receive the data. */
					0 );

				if( xReturned < 0 )
				{
					break;
				}

			} while( ( xTaskGetTickCount() - xTimeOnEntering ) < xReceiveTimeOut );
		}

		/* Close this socket before looping back to create another. */
		FreeRTOS_closesocket( xSocket );

		/* Pause for a short while to ensure the network is not too
		congested. */
		vTaskDelay( echoLOOP_DELAY );
	}
}
Beispiel #10
0
static BaseType_t prvOpenURL( HTTPClient_t *pxClient )
{
BaseType_t xRc;
char pcSlash[ 2 ];

	pxClient->bits.ulFlags = 0;

	#if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 )
	{
		if( strchr( pxClient->pcUrlData, ipconfigHTTP_REQUEST_CHARACTER ) != NULL )
		{
		size_t xResult;

			xResult = uxApplicationHTTPHandleRequestHook( pxClient->pcUrlData, pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ) );
			if( xResult > 0 )
			{
				strcpy( pxClient->pxParent->pcContentsType, "text/html" );
				snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ),
					"Content-Length: %d\r\n", ( int ) xResult );
				xRc = prvSendReply( pxClient, WEB_REPLY_OK );	/* "Requested file action OK" */
				if( xRc > 0 )
				{
					xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pcCurrentFilename, xResult, 0 );
				}
				/* Although against the coding standard of FreeRTOS, a return is
				done here  to simplify this conditional code. */
				return xRc;
			}
		}
	}
	#endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */

	if( pxClient->pcUrlData[ 0 ] != '/' )
	{
		/* Insert a slash before the file name. */
		pcSlash[ 0 ] = '/';
		pcSlash[ 1 ] = '\0';
	}
	else
	{
		/* The browser provided a starting '/' already. */
		pcSlash[ 0 ] = '\0';
	}
	snprintf( pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ), "%s%s%s",
		pxClient->pcRootDir,
		pcSlash,
		pxClient->pcUrlData);

	pxClient->pxFileHandle = ff_fopen( pxClient->pcCurrentFilename, "rb" );

	FreeRTOS_printf( ( "Open file '%s': %s\n", pxClient->pcCurrentFilename,
		pxClient->pxFileHandle != NULL ? "Ok" : strerror( stdioGET_ERRNO() ) ) );

	if( pxClient->pxFileHandle == NULL )
	{
		/* "404 File not found". */
		xRc = prvSendReply( pxClient, WEB_NOT_FOUND );
	}
	else
	{
		pxClient->uxBytesLeft = ( size_t ) pxClient->pxFileHandle->ulFileSize;
		xRc = prvSendFile( pxClient );
	}

	return xRc;
}