diff --git a/.github/lexicon.txt b/.github/lexicon.txt index d7caa6248e..3e6d4d913d 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -230,6 +230,7 @@ egetlinklayeraddress ehertype einitialwait einprogress +einval einvalidchecksum einvaliddata eleasedaddress @@ -785,6 +786,7 @@ pvparameters pvportmalloc pvportmallocsocket pvsearchid +pvsocketid pvsource pxackmessage pxaddr @@ -981,6 +983,7 @@ skipnamefield snd snprintf sockaddr +socketid socketset sockopt sof @@ -1392,8 +1395,10 @@ vrxfaultinjection vsocketbind vsocketclose vsocketclosenexttime +vsocketgetsocketid vsocketlistennexttime vsocketselect +vsocketsetsocketid vsocketwakeupuser vtasklist vtasknotifygivefromisr diff --git a/source/FreeRTOS_Sockets.c b/source/FreeRTOS_Sockets.c index 504016726b..a782304fea 100644 --- a/source/FreeRTOS_Sockets.c +++ b/source/FreeRTOS_Sockets.c @@ -4797,6 +4797,49 @@ BaseType_t xSocketValid( const ConstSocket_t xSocket ) #endif /* ipconfigUSE_TCP */ /*-----------------------------------------------------------*/ +/** + * @brief Set the value of the SocketID of a socket. + * @param[in] xSocket: The socket whose ID should be set. + * @param[in] pvSocketID: The new value for the SocketID. + * @return Zero if the socket was valid, otherwise -EINVAL. + */ +BaseType_t xSocketSetSocketID( const Socket_t xSocket, + void * pvSocketID ) +{ + FreeRTOS_Socket_t * pxSocket = ( FreeRTOS_Socket_t * ) xSocket; + BaseType_t xReturn = -pdFREERTOS_ERRNO_EINVAL; + + if( xSocketValid( pxSocket ) ) + { + xReturn = 0; + pxSocket->pvSocketID = pvSocketID; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +/** + * @brief Retrieve the SocketID that is associated with a socket. + * @param[in] xSocket: The socket whose ID should be returned. + * @return The current value of pvSocketID, or NULL in case + * the socket pointer is not valid or when the ID was not + * yet set. + */ +void * pvSocketGetSocketID( const ConstSocket_t xSocket ) +{ + const FreeRTOS_Socket_t * pxSocket = ( const FreeRTOS_Socket_t * ) xSocket; + void * pvReturn = NULL; + + if( xSocketValid( pxSocket ) ) + { + pvReturn = pxSocket->pvSocketID; + } + + return pvReturn; +} +/*-----------------------------------------------------------*/ + #if ( ( ipconfigHAS_PRINTF != 0 ) && ( ipconfigUSE_TCP == 1 ) ) /** diff --git a/source/include/FreeRTOS_IP_Private.h b/source/include/FreeRTOS_IP_Private.h index 4a347f02dc..411cf9cb1b 100644 --- a/source/include/FreeRTOS_IP_Private.h +++ b/source/include/FreeRTOS_IP_Private.h @@ -680,6 +680,13 @@ typedef struct xSOCKET EventBits_t xSocketBits; /**< These bits indicate the events which have actually occurred. * They are maintained by the IP-task */ #endif /* ipconfigSUPPORT_SELECT_FUNCTION */ + + /* This field is only only by the user, and can be accessed with + * vSocketSetSocketID() / vSocketGetSocketID(). + * All fields of a socket will be cleared by memset() in FreeRTOS_socket(). + */ + void * pvSocketID; + /* TCP/UDP specific fields: */ /* Before accessing any member of this structure, it should be confirmed */ /* that the protocol corresponds with the type of structure */ diff --git a/source/include/FreeRTOS_Sockets.h b/source/include/FreeRTOS_Sockets.h index f3095268d1..cf3a20c57e 100644 --- a/source/include/FreeRTOS_Sockets.h +++ b/source/include/FreeRTOS_Sockets.h @@ -366,6 +366,14 @@ void FreeRTOS_netstat( void ); +/* This option adds the possibility to have a user-ID attached to a socket. + * The type of this ID is a void *. Both UDP and TCP sockets have + * this ID. It has a default value of NULL. + */ + BaseType_t xSocketSetSocketID( const Socket_t xSocket, + void * pvSocketID ); + + void * pvSocketGetSocketID( const ConstSocket_t xSocket ); /* End TCP Socket Attributes. */ diff --git a/test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_GenericAPI_utest.c b/test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_GenericAPI_utest.c index 4dbd0f4cf0..f93ce1626a 100644 --- a/test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_GenericAPI_utest.c +++ b/test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_GenericAPI_utest.c @@ -2903,6 +2903,89 @@ void test_FreeRTOS_maywrite_HappyPath( void ) TEST_ASSERT_EQUAL( 0x3344, xReturn ); } +/* + * @brief Test setting socket ID when the socket is NULL. + */ +void test_xSocketSetSocketID_NULLSocket( void ) +{ + BaseType_t xReturn; + + xReturn = xSocketSetSocketID( NULL, NULL ); + + TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EINVAL, xReturn ); +} + +/* + * @brief Test setting socket ID when the socket is invalid. + */ +void test_xSocketSetSocketID_InvalidSocket( void ) +{ + BaseType_t xReturn; + + xReturn = xSocketSetSocketID( FREERTOS_INVALID_SOCKET, NULL ); + + TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EINVAL, xReturn ); +} + +/* + * @brief Test setting socket ID when the socket is Valid. + */ +void test_xSocketSetSocketID_ValidSocket( void ) +{ + BaseType_t xReturn; + FreeRTOS_Socket_t xSocket; + BaseType_t AnchorVariable; + + memset( &xSocket, 0, sizeof( xSocket ) ); + + xReturn = xSocketSetSocketID( &xSocket, &AnchorVariable ); + + TEST_ASSERT_EQUAL( 0, xReturn ); + TEST_ASSERT_EQUAL( &AnchorVariable, xSocket.pvSocketID ); +} + +/* + * @brief Test setting socket ID when the socket is NULL. + */ +void test_pvSocketGetSocketID_NULLSocket( void ) +{ + void * pvReturn; + + pvReturn = pvSocketGetSocketID( NULL ); + + TEST_ASSERT_EQUAL( NULL, pvReturn ); +} + +/* + * @brief Test setting socket ID when the socket is invalid. + */ +void test_pvSocketGetSocketID_InvalidSocket( void ) +{ + void * pvReturn; + + pvReturn = pvSocketGetSocketID( FREERTOS_INVALID_SOCKET ); + + TEST_ASSERT_EQUAL( NULL, pvReturn ); +} + +/* + * @brief Test setting socket ID when the socket is Valid. + */ +void test_pvSocketGetSocketID_ValidSocket( void ) +{ + BaseType_t pvReturn; + FreeRTOS_Socket_t xSocket; + BaseType_t AnchorVariable; + + memset( &xSocket, 0, sizeof( xSocket ) ); + + xSocket.pvSocketID = &AnchorVariable; + + pvReturn = pvSocketGetSocketID( &xSocket ); + + TEST_ASSERT_EQUAL( &AnchorVariable, pvReturn ); +} + /* * @brief This function just prints out some data. It is expected to make calls to the * below functions when IP stack is not initialised.