in amazon-freertos/lib/FreeRTOS-Plus-TCP/source/FreeRTOS_TCP_IP.c [1430:1599]
void vTCPStateChange( FreeRTOS_Socket_t *pxSocket, enum eTCP_STATE eTCPState )
{
FreeRTOS_Socket_t *xParent = NULL;
BaseType_t bBefore = ( BaseType_t ) NOW_CONNECTED( pxSocket->u.xTCP.ucTCPState ); /* Was it connected ? */
BaseType_t bAfter = ( BaseType_t ) NOW_CONNECTED( eTCPState ); /* Is it connected now ? */
#if( ipconfigHAS_DEBUG_PRINTF != 0 )
BaseType_t xPreviousState = ( BaseType_t ) pxSocket->u.xTCP.ucTCPState;
#endif
#if( ipconfigUSE_CALLBACKS == 1 )
FreeRTOS_Socket_t *xConnected = NULL;
#endif
/* Has the connected status changed? */
if( bBefore != bAfter )
{
/* Is the socket connected now ? */
if( bAfter != pdFALSE )
{
/* if bPassQueued is true, this socket is an orphan until it gets connected. */
if( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED )
{
/* Now that it is connected, find it's parent. */
if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
{
xParent = pxSocket;
}
else
{
xParent = pxSocket->u.xTCP.pxPeerSocket;
configASSERT( xParent != NULL );
}
if( xParent != NULL )
{
if( xParent->u.xTCP.pxPeerSocket == NULL )
{
xParent->u.xTCP.pxPeerSocket = pxSocket;
}
xParent->xEventBits |= eSOCKET_ACCEPT;
#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
{
/* Library support FreeRTOS_select(). Receiving a new
connection is being translated as a READ event. */
if( ( xParent->xSelectBits & eSELECT_READ ) != 0 )
{
xParent->xEventBits |= ( eSELECT_READ << SOCKET_EVENT_BIT_COUNT );
}
}
#endif
#if( ipconfigUSE_CALLBACKS == 1 )
{
if( ( ipconfigIS_VALID_PROG_ADDRESS( xParent->u.xTCP.pxHandleConnected ) != pdFALSE ) &&
( xParent->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED ) )
{
/* The listening socket does not become connected itself, in stead
a child socket is created.
Postpone a call the OnConnect event until the end of this function. */
xConnected = xParent;
}
}
#endif
}
/* Don't need to access the parent socket anymore, so the
reference 'pxPeerSocket' may be cleared. */
pxSocket->u.xTCP.pxPeerSocket = NULL;
pxSocket->u.xTCP.bits.bPassQueued = pdFALSE_UNSIGNED;
/* When true, this socket may be returned in a call to accept(). */
pxSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED;
}
else
{
pxSocket->xEventBits |= eSOCKET_CONNECT;
#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
{
if( pxSocket->xSelectBits & eSELECT_WRITE )
{
pxSocket->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
}
}
#endif
}
}
else /* bAfter == pdFALSE, connection is closed. */
{
/* Notify/wake-up the socket-owner by setting a semaphore. */
pxSocket->xEventBits |= eSOCKET_CLOSED;
#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
{
if( ( pxSocket->xSelectBits & eSELECT_EXCEPT ) != 0 )
{
pxSocket->xEventBits |= ( eSELECT_EXCEPT << SOCKET_EVENT_BIT_COUNT );
}
}
#endif
}
#if( ipconfigUSE_CALLBACKS == 1 )
{
if( ( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleConnected ) != pdFALSE ) && ( xConnected == NULL ) )
{
/* The 'connected' state has changed, call the user handler. */
xConnected = pxSocket;
}
}
#endif /* ipconfigUSE_CALLBACKS */
if( prvTCPSocketIsActive( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) == pdFALSE )
{
/* Now the socket isn't in an active state anymore so it
won't need further attention of the IP-task.
Setting time-out to zero means that the socket won't get checked during
timer events. */
pxSocket->u.xTCP.usTimeout = 0u;
}
}
else
{
if( eTCPState == eCLOSED )
{
/* Socket goes to status eCLOSED because of a RST.
When nobody owns the socket yet, delete it. */
if( ( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED ) ||
( pxSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
{
FreeRTOS_debug_printf( ( "vTCPStateChange: Closing socket\n" ) );
if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
{
FreeRTOS_closesocket( pxSocket );
}
}
}
}
/* Fill in the new state. */
pxSocket->u.xTCP.ucTCPState = ( uint8_t ) eTCPState;
/* touch the alive timers because moving to another state. */
prvTCPTouchSocket( pxSocket );
#if( ipconfigHAS_DEBUG_PRINTF == 1 )
{
if( ( xTCPWindowLoggingLevel >= 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
FreeRTOS_debug_printf( ( "Socket %d -> %lxip:%u State %s->%s\n",
pxSocket->usLocalPort,
pxSocket->u.xTCP.ulRemoteIP,
pxSocket->u.xTCP.usRemotePort,
FreeRTOS_GetTCPStateName( ( UBaseType_t ) xPreviousState ),
FreeRTOS_GetTCPStateName( ( UBaseType_t ) eTCPState ) ) );
}
#endif /* ipconfigHAS_DEBUG_PRINTF */
#if( ipconfigUSE_CALLBACKS == 1 )
{
if( xConnected != NULL )
{
/* The 'connected' state has changed, call the OnConnect handler of the parent. */
xConnected->u.xTCP.pxHandleConnected( ( Socket_t * ) xConnected, bAfter );
}
}
#endif
if( xParent != NULL )
{
vSocketWakeUpUser( xParent );
}
}