Refer to Sending
UDP Data (zero copy interface) for how to send data using a UDP zero copy interface.
The FreeRTOS_send() TCP/IP stack API
function is used to send data to a TCP socket. Data
can only be sent after the socket has been
created,
configured, bound, and connected to a remote socket using the
FreeRTOS_connect()
API function, or it can accept connections
from a remote socket.
The source code snippets below show a function that creates a socket, sends data to the socket using the
zero copy interface, then gracefully shuts down and closes the socket. Both IPv4 and IPv6 use cases are shown.
Note that this socket is not explicitly bound to a port number - causing it to be bound automatically inside
the FreeRTOS_connect() API function.
IPv4
void vTCPSend( char *pcBufferToTransmit, const size_t xTotalLengthToSend )
{
Socket_t xSocket;
struct freertos_sockaddr xRemoteAddress;
BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
TaskHandle_t xRxTask = NULL;
size_t xLenToSend;
xRemoteAddress.sin_port = FreeRTOS_htons( 1500 );
xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 0, 200 );
xSocket = FreeRTOS_socket( FREERTOS_AF_INET,
FREERTOS_SOCK_STREAM,
FREERTOS_IPPROTO_TCP );
configASSERT( xSocket != FREERTOS_INVALID_SOCKET );
if( FreeRTOS_connect( xSocket, &xRemoteAddress, sizeof( xRemoteAddress ) ) == 0 )
{
while( xAlreadyTransmitted < xTotalLengthToSend )
{
BaseType_t xAvlSpace = 0;
BaseType_t xBytesToSend = 0;
uint8_t *pucTCPZeroCopyStrmBuffer;
pucTCPZeroCopyStrmBuffer = FreeRTOS_get_tx_head( xSocket, &xAvlSpace );
if(pucTCPZeroCopyStrmBuffer)
{
if((xTotalLengthToSend - xAlreadyTransmitted) > xAvlSpace)
{
xBytesToSend = xAvlSpace;
}
else
{
xBytesToSend = (xTotalLengthToSend - xAlreadyTransmitted);
}
memcpy( pucTCPZeroCopyStrmBuffer,
( void * ) (( (uint8_t *) pcBufferToTransmit ) + xAlreadyTransmitted),
xBytesToSend);
}
else
{
break;
}
xBytesSent = FreeRTOS_send(
xSocket,
NULL,
xBytesToSend,
0 );
if( xBytesSent >= 0 )
{
xAlreadyTransmitted += xBytesSent;
}
else
{
break;
}
}
}
FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );
while( FreeRTOS_recv( xSocket, pcBufferToTransmit, xTotalLengthToSend, 0 ) >= 0 )
{
vTaskDelay( pdTICKS_TO_MS( 250 ) );
}
FreeRTOS_closesocket( xSocket );
}
IPv4 Example using FreeRTOS_send() with the zero copy calling semantics
IPv6
void vTCPSend( char *pcBufferToTransmit, const size_t xTotalLengthToSend )
{
Socket_t xSocket;
struct freertos_sockaddr xRemoteAddress;
BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
TaskHandle_t xRxTask = NULL;
size_t xLenToSend;
xRemoteAddress.sin_port = FreeRTOS_htons( 1500 );
FreeRTOS_inet_pton6( "2001:470:ed44::9c08:38cc:599f:f62a",
(void *) xRemoteAddress.sin_address.xIP_IPv6.ucBytes )
xSocket = FreeRTOS_socket( FREERTOS_AF_INET6,
FREERTOS_SOCK_STREAM,
FREERTOS_IPPROTO_TCP );
configASSERT( xSocket != FREERTOS_INVALID_SOCKET );
if( FreeRTOS_connect( xSocket, &xRemoteAddress, sizeof( xRemoteAddress ) ) == 0 )
{
while( xAlreadyTransmitted < xTotalLengthToSend )
{
BaseType_t xAvlSpace = 0;
BaseType_t xBytesToSend = 0;
uint8_t *pucTCPZeroCopyStrmBuffer;
pucTCPZeroCopyStrmBuffer = FreeRTOS_get_tx_head( xSocket, &xAvlSpace );
if(pucTCPZeroCopyStrmBuffer)
{
if((xTotalLengthToSend - xAlreadyTransmitted) > xAvlSpace)
{
xBytesToSend = xAvlSpace;
}
else
{
xBytesToSend = (xTotalLengthToSend - xAlreadyTransmitted);
}
memcpy( pucTCPZeroCopyStrmBuffer,
( void * ) (( (uint8_t *) pcBufferToTransmit ) + xAlreadyTransmitted),
xBytesToSend);
}
else
{
break;
}
xBytesSent = FreeRTOS_send(
xSocket,
NULL,
xBytesToSend,
0 );
if( xBytesSent >= 0 )
{
xAlreadyTransmitted += xBytesSent;
}
else
{
break;
}
}
}
FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );
while( FreeRTOS_recv( xSocket, pcBufferToTransmit, xTotalLengthToSend, 0 ) >= 0 )
{
vTaskDelay( pdTICKS_TO_MS( 250 ) );
}
FreeRTOS_closesocket( xSocket );
}
IPv6 Example using FreeRTOS_send() with the zero copy calling semantics
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.