|
118 | 118 | /* |
119 | 119 | * Create the DHCP socket, if it has not been created already. |
120 | 120 | */ |
121 | | - _static void prvCreateDHCPSocket( const NetworkEndPoint_t * pxEndPoint ); |
| 121 | + _static void prvCreateDHCPSocket( NetworkEndPoint_t * pxEndPoint ); |
122 | 122 |
|
123 | 123 | /* |
124 | 124 | * Close the DHCP socket, only when not in use anymore (i.e. xDHCPSocketUserCount = 0). |
125 | 125 | */ |
126 | | - static void prvCloseDHCPSocket( const NetworkEndPoint_t * pxEndPoint ); |
| 126 | + static void prvCloseDHCPSocket( NetworkEndPoint_t * pxEndPoint ); |
127 | 127 |
|
128 | 128 | static void vDHCPProcessEndPoint( BaseType_t xReset, |
129 | 129 | BaseType_t xDoCheck, |
|
214 | 214 | FreeRTOS_debug_printf( ( "DHCP wrong state: expect: %d got: %d : ignore\n", |
215 | 215 | EP_DHCPData.eExpectedState, EP_DHCPData.eDHCPState ) ); |
216 | 216 | } |
217 | | - else if( xDHCPv4Socket != NULL ) /* If there is a socket, check for incoming messages first. */ |
| 217 | + else if( EP_DHCPData.xDHCPSocket != NULL ) /* If there is a socket, check for incoming messages first. */ |
218 | 218 | { |
219 | 219 | /* No need to initialise 'pucUDPPayload', it just looks nicer. */ |
220 | 220 | uint8_t * pucUDPPayload = NULL; |
221 | 221 | const DHCPMessage_IPv4_t * pxDHCPMessage; |
222 | 222 | int32_t lBytes; |
223 | 223 |
|
224 | | - while( xDHCPv4Socket != NULL ) |
| 224 | + while( EP_DHCPData.xDHCPSocket != NULL ) |
225 | 225 | { |
226 | 226 | BaseType_t xRecvFlags = FREERTOS_ZERO_COPY + FREERTOS_MSG_PEEK; |
227 | 227 | NetworkEndPoint_t * pxIterator = NULL; |
228 | 228 |
|
229 | 229 | /* Peek the next UDP message. */ |
230 | | - lBytes = FreeRTOS_recvfrom( xDHCPv4Socket, &( pucUDPPayload ), 0, xRecvFlags, NULL, NULL ); |
| 230 | + lBytes = FreeRTOS_recvfrom( EP_DHCPData.xDHCPSocket, &( pucUDPPayload ), 0, xRecvFlags, NULL, NULL ); |
231 | 231 |
|
232 | 232 | if( lBytes < ( ( int32_t ) sizeof( DHCPMessage_IPv4_t ) ) ) |
233 | 233 | { |
|
282 | 282 | { |
283 | 283 | /* Target not found, fetch the message and delete it. */ |
284 | 284 | /* PAss the address of a pointer pucUDPPayload, because zero-copy is used. */ |
285 | | - lBytes = FreeRTOS_recvfrom( xDHCPv4Socket, &( pucUDPPayload ), 0, FREERTOS_ZERO_COPY, NULL, NULL ); |
| 285 | + lBytes = FreeRTOS_recvfrom( EP_DHCPData.xDHCPSocket, &( pucUDPPayload ), 0, FREERTOS_ZERO_COPY, NULL, NULL ); |
286 | 286 |
|
287 | 287 | if( ( lBytes > 0 ) && ( pucUDPPayload != NULL ) ) |
288 | 288 | { |
|
305 | 305 | } |
306 | 306 | } |
307 | 307 |
|
| 308 | +/** |
| 309 | + * @brief Stop the DHCP process. Close the DHCP socket when it's no longer used by any end-point. |
| 310 | + * |
| 311 | + * @param[in] pxEndPoint The end-point for which we want to stop the DHCP process. |
| 312 | + */ |
| 313 | + void vDHCPStop( struct xNetworkEndPoint * pxEndPoint ) |
| 314 | + { |
| 315 | + /* Disable the DHCP timer. */ |
| 316 | + vIPSetDHCP_RATimerEnableState( pxEndPoint, pdFALSE ); |
| 317 | + |
| 318 | + /* Close socket to ensure packets don't queue on it. */ |
| 319 | + prvCloseDHCPSocket( pxEndPoint ); |
| 320 | + } |
| 321 | + |
308 | 322 | /** |
309 | 323 | * @brief Called by vDHCPProcessEndPoint(), this function handles the state 'eWaitingOffer'. |
310 | 324 | * If there is a reply, it will be examined, if there is a time-out, there may be a new |
|
564 | 578 | #endif /* ipconfigUSE_DHCP_HOOK */ |
565 | 579 | { |
566 | 580 | /* See if prvInitialiseDHCP() has creates a socket. */ |
567 | | - if( xDHCPv4Socket == NULL ) |
| 581 | + if( EP_DHCPData.xDHCPSocket == NULL ) |
568 | 582 | { |
569 | 583 | xGivingUp = pdTRUE; |
570 | 584 | } |
|
618 | 632 | /* Resend the request at the appropriate time to renew the lease. */ |
619 | 633 | prvCreateDHCPSocket( pxEndPoint ); |
620 | 634 |
|
621 | | - if( xDHCPv4Socket != NULL ) |
| 635 | + if( EP_DHCPData.xDHCPSocket != NULL ) |
622 | 636 | { |
623 | 637 | uint32_t ulID = 0U; |
624 | 638 |
|
|
829 | 843 | * using it. |
830 | 844 | * @param[in] pxEndPoint The end-point that stops using the socket. |
831 | 845 | */ |
832 | | - static void prvCloseDHCPSocket( const NetworkEndPoint_t * pxEndPoint ) |
| 846 | + void prvCloseDHCPSocket( NetworkEndPoint_t * pxEndPoint ) |
833 | 847 | { |
834 | | - ( void ) pxEndPoint; |
835 | | - |
836 | | - if( ( xDHCPv4Socket != NULL ) && ( xDHCPSocketUserCount > 0 ) ) |
| 848 | + if( ( EP_DHCPData.xDHCPSocket == NULL ) || ( EP_DHCPData.xDHCPSocket != xDHCPv4Socket ) ) |
| 849 | + { |
| 850 | + /* the socket can not be closed. */ |
| 851 | + } |
| 852 | + else if( xDHCPSocketUserCount > 0 ) |
837 | 853 | { |
838 | 854 | xDHCPSocketUserCount--; |
839 | 855 |
|
|
844 | 860 | ( void ) vSocketClose( xDHCPv4Socket ); |
845 | 861 | xDHCPv4Socket = NULL; |
846 | 862 | } |
| 863 | + |
| 864 | + EP_DHCPData.xDHCPSocket = NULL; |
847 | 865 | } |
848 | 866 | else |
849 | 867 | { |
|
862 | 880 | * @brief Create a DHCP socket with the defined timeouts. The same socket |
863 | 881 | * will be shared among all end-points that need DHCP. |
864 | 882 | */ |
865 | | - _static void prvCreateDHCPSocket( const NetworkEndPoint_t * pxEndPoint ) |
| 883 | + _static void prvCreateDHCPSocket( NetworkEndPoint_t * pxEndPoint ) |
866 | 884 | { |
867 | 885 | struct freertos_sockaddr xAddress; |
868 | 886 | BaseType_t xReturn; |
869 | 887 | TickType_t xTimeoutTime = ( TickType_t ) 0; |
870 | 888 |
|
871 | | - if( xDHCPv4Socket == NULL ) /* Create the socket, if it has not already been created. */ |
| 889 | + if( ( xDHCPv4Socket != NULL ) && ( EP_DHCPData.xDHCPSocket == xDHCPv4Socket ) ) |
| 890 | + { |
| 891 | + /* the socket is still valid. */ |
| 892 | + } |
| 893 | + else if( xDHCPv4Socket == NULL ) /* Create the socket, if it has not already been created. */ |
872 | 894 | { |
873 | 895 | xDHCPv4Socket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); |
874 | 896 | configASSERT( xSocketValid( xDHCPv4Socket ) == pdTRUE ); |
|
883 | 905 | ( void ) FreeRTOS_setsockopt( xDHCPv4Socket, 0, FREERTOS_SO_RCVTIMEO, &( xTimeoutTime ), sizeof( TickType_t ) ); |
884 | 906 | ( void ) FreeRTOS_setsockopt( xDHCPv4Socket, 0, FREERTOS_SO_SNDTIMEO, &( xTimeoutTime ), sizeof( TickType_t ) ); |
885 | 907 |
|
| 908 | + memset( &xAddress, 0, sizeof( xAddress ) ); |
| 909 | + xAddress.sin_family = FREERTOS_AF_INET4; |
| 910 | + xAddress.sin_len = ( uint8_t ) sizeof( xAddress ); |
886 | 911 | /* Bind to the standard DHCP client port. */ |
887 | 912 | xAddress.sin_port = ( uint16_t ) dhcpCLIENT_PORT_IPv4; |
888 | 913 | xReturn = vSocketBind( xDHCPv4Socket, &xAddress, sizeof( xAddress ), pdFALSE ); |
889 | 914 | xDHCPSocketUserCount = 1; |
| 915 | + EP_DHCPData.xDHCPSocket = xDHCPv4Socket; |
890 | 916 | FreeRTOS_printf( ( "DHCP-socket[%02x-%02x]: DHCP Socket Create\n", |
891 | 917 | pxEndPoint->xMACAddress.ucBytes[ 4 ], |
892 | 918 | pxEndPoint->xMACAddress.ucBytes[ 5 ] ) ); |
|
901 | 927 | { |
902 | 928 | /* Change to NULL for easier testing. */ |
903 | 929 | xDHCPv4Socket = NULL; |
| 930 | + EP_DHCPData.xDHCPSocket = NULL; |
904 | 931 | } |
905 | 932 | } |
906 | 933 | else |
907 | 934 | { |
908 | 935 | xDHCPSocketUserCount++; |
| 936 | + EP_DHCPData.xDHCPSocket = xDHCPv4Socket; |
909 | 937 | } |
910 | 938 |
|
911 | 939 | FreeRTOS_printf( ( "prvCreateDHCPSocket[%02x-%02x]: %s, user count %d\n", |
|
1248 | 1276 | ( void ) memset( &( xSet ), 0, sizeof( xSet ) ); |
1249 | 1277 |
|
1250 | 1278 | /* Passing the address of a pointer (pucUDPPayload) because FREERTOS_ZERO_COPY is used. */ |
1251 | | - lBytes = FreeRTOS_recvfrom( xDHCPv4Socket, &pucUDPPayload, 0U, FREERTOS_ZERO_COPY, NULL, NULL ); |
| 1279 | + lBytes = FreeRTOS_recvfrom( EP_DHCPData.xDHCPSocket, &pucUDPPayload, 0U, FREERTOS_ZERO_COPY, NULL, NULL ); |
1252 | 1280 |
|
1253 | 1281 | if( lBytes > 0 ) |
1254 | 1282 | { |
|
1504 | 1532 | &( uxOptionsLength ), |
1505 | 1533 | pxEndPoint ); |
1506 | 1534 |
|
1507 | | - /* MISRA Ref 11.4.1 [Socket error and integer to pointer conversion] */ |
1508 | | - /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-114 */ |
1509 | | - /* coverity[misra_c_2012_rule_11_4_violation] */ |
1510 | | - if( ( xSocketValid( xDHCPv4Socket ) == pdTRUE ) && ( pucUDPPayloadBuffer != NULL ) ) |
| 1535 | + if( ( xSocketValid( EP_DHCPData.xDHCPSocket ) == pdTRUE ) && ( pucUDPPayloadBuffer != NULL ) ) |
1511 | 1536 | { |
1512 | 1537 | /* Copy in the IP address being requested. */ |
1513 | 1538 |
|
|
1528 | 1553 | FreeRTOS_debug_printf( ( "vDHCPProcess: reply %xip\n", ( unsigned ) FreeRTOS_ntohl( EP_DHCPData.ulOfferedIPAddress ) ) ); |
1529 | 1554 | iptraceSENDING_DHCP_REQUEST(); |
1530 | 1555 |
|
1531 | | - xDHCPv4Socket->pxEndPoint = pxEndPoint; |
| 1556 | + EP_DHCPData.xDHCPSocket->pxEndPoint = pxEndPoint; |
1532 | 1557 |
|
1533 | | - if( FreeRTOS_sendto( xDHCPv4Socket, pucUDPPayloadBuffer, sizeof( DHCPMessage_IPv4_t ) + uxOptionsLength, FREERTOS_ZERO_COPY, &xAddress, ( socklen_t ) sizeof( xAddress ) ) == 0 ) |
| 1558 | + if( FreeRTOS_sendto( EP_DHCPData.xDHCPSocket, pucUDPPayloadBuffer, sizeof( DHCPMessage_IPv4_t ) + uxOptionsLength, FREERTOS_ZERO_COPY, &xAddress, ( socklen_t ) sizeof( xAddress ) ) == 0 ) |
1534 | 1559 | { |
1535 | 1560 | /* The packet was not successfully queued for sending and must be |
1536 | 1561 | * returned to the stack. */ |
|
1579 | 1604 | /* MISRA Ref 11.4.1 [Socket error and integer to pointer conversion] */ |
1580 | 1605 | /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-114 */ |
1581 | 1606 | /* coverity[misra_c_2012_rule_11_4_violation] */ |
1582 | | - if( ( xSocketValid( xDHCPv4Socket ) == pdTRUE ) && ( pucUDPPayloadBuffer != NULL ) ) |
| 1607 | + if( ( xSocketValid( EP_DHCPData.xDHCPSocket ) == pdTRUE ) && ( pucUDPPayloadBuffer != NULL ) ) |
1583 | 1608 | { |
1584 | 1609 | const void * pvCopySource; |
1585 | 1610 | void * pvCopyDest; |
|
1608 | 1633 | uxOptionsLength -= dhcpOPTION_50_SIZE; |
1609 | 1634 | } |
1610 | 1635 |
|
1611 | | - xDHCPv4Socket->pxEndPoint = pxEndPoint; |
| 1636 | + EP_DHCPData.xDHCPSocket->pxEndPoint = pxEndPoint; |
1612 | 1637 |
|
1613 | | - if( FreeRTOS_sendto( xDHCPv4Socket, |
| 1638 | + if( FreeRTOS_sendto( EP_DHCPData.xDHCPSocket, |
1614 | 1639 | pucUDPPayloadBuffer, |
1615 | 1640 | sizeof( DHCPMessage_IPv4_t ) + uxOptionsLength, |
1616 | 1641 | FREERTOS_ZERO_COPY, |
|
0 commit comments