|
52 | 52 | #include "FreeRTOS_DNS.h"
|
53 | 53 | #include "NetworkBufferManagement.h"
|
54 | 54 | #include "FreeRTOS_Routing.h"
|
55 |
| - |
| 55 | +#if ( ipconfigSUPPORT_IP_MULTICAST != 0 ) |
| 56 | + #include "FreeRTOS_IGMP.h" |
| 57 | +#endif |
56 | 58 | #if ( ipconfigUSE_TCP_MEM_STATS != 0 )
|
57 | 59 | #include "tcp_mem_stats.h"
|
58 | 60 | #endif
|
@@ -738,6 +740,11 @@ Socket_t FreeRTOS_socket( BaseType_t xDomain,
|
738 | 740 | pxSocket->u.xUDP.uxMaxPackets = ( UBaseType_t ) ipconfigUDP_MAX_RX_PACKETS;
|
739 | 741 | }
|
740 | 742 | #endif /* ipconfigUDP_MAX_RX_PACKETS > 0 */
|
| 743 | + |
| 744 | + #if ( ipconfigSUPPORT_IP_MULTICAST != 0 ) |
| 745 | + pxSocket->u.xUDP.ucMulticastTTL = ipconfigMULTICAST_DEFAULT_TTL; |
| 746 | + vListInitialise( &pxSocket->u.xUDP.xMulticastGroupsList ); |
| 747 | + #endif |
741 | 748 | }
|
742 | 749 |
|
743 | 750 | #if ( ipconfigUSE_TCP == 1 )
|
@@ -1432,6 +1439,17 @@ static int32_t prvSendUDPPacket( const FreeRTOS_Socket_t * pxSocket,
|
1432 | 1439 | pxNetworkBuffer->usPort = pxDestinationAddress->sin_port;
|
1433 | 1440 | pxNetworkBuffer->usBoundPort = ( uint16_t ) socketGET_SOCKET_PORT( pxSocket );
|
1434 | 1441 |
|
| 1442 | + #if ( ipconfigSUPPORT_IP_MULTICAST != 0 ) |
| 1443 | + if( xIsIPv4Multicast( pxDestinationAddress->sin_address.ulIP_IPv4 ) ) |
| 1444 | + { |
| 1445 | + pxNetworkBuffer->ucSendTTL = pxSocket->u.xUDP.ucMulticastTTL; |
| 1446 | + } |
| 1447 | + else |
| 1448 | + { |
| 1449 | + pxNetworkBuffer->ucSendTTL = ipconfigUDP_TIME_TO_LIVE; |
| 1450 | + } |
| 1451 | + #endif |
| 1452 | + |
1435 | 1453 | /* The socket options are passed to the IP layer in the
|
1436 | 1454 | * space that will eventually get used by the Ethernet header. */
|
1437 | 1455 | pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ] = pxSocket->ucSocketOptions;
|
@@ -2132,6 +2150,18 @@ void * vSocketClose( FreeRTOS_Socket_t * pxSocket )
|
2132 | 2150 | #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
|
2133 | 2151 | }
|
2134 | 2152 |
|
| 2153 | + #if ( ipconfigSUPPORT_IP_MULTICAST != 0 ) |
| 2154 | + if( pxSocket->ucProtocol == ipPROTOCOL_UDP ) |
| 2155 | + { |
| 2156 | + /* Un-register all multicast groups that might have been added. */ |
| 2157 | + while( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xMulticastGroupsList ) ) > 0U ) |
| 2158 | + { |
| 2159 | + MCastGroupDesc_t * pMCD = ( MCastGroupDesc_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->u.xUDP.xMulticastGroupsList ) ); |
| 2160 | + ( void ) vModifyMulticastMembership( pMCD, eSocketOptDropMembership ); |
| 2161 | + } |
| 2162 | + } |
| 2163 | + #endif /* ( ipconfigSUPPORT_IP_MULTICAST != 0 ) */ |
| 2164 | + |
2135 | 2165 | /* Now the socket is not bound the list of waiting packets can be
|
2136 | 2166 | * drained. */
|
2137 | 2167 | if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_UDP )
|
@@ -2929,6 +2959,20 @@ BaseType_t FreeRTOS_setsockopt( Socket_t xSocket,
|
2929 | 2959 | break;
|
2930 | 2960 | #endif /* ipconfigUSE_TCP == 1 */
|
2931 | 2961 |
|
| 2962 | + #if ( ipconfigSUPPORT_IP_MULTICAST != 0 ) |
| 2963 | + case FREERTOS_SO_IP_MULTICAST_TTL: |
| 2964 | + case FREERTOS_SO_IP_ADD_MEMBERSHIP: |
| 2965 | + case FREERTOS_SO_IP_DROP_MEMBERSHIP: |
| 2966 | + /* Use extern here, because we don't want to expose xSetMulticastSocketOption through .h files */ |
| 2967 | + extern BaseType_t xSetMulticastSocketOption( Socket_t xSocket, |
| 2968 | + int32_t lLevel, |
| 2969 | + int32_t lOptionName, |
| 2970 | + const void * pvOptionValue, |
| 2971 | + size_t uxOptionLength ); |
| 2972 | + xReturn = xSetMulticastSocketOption( xSocket, lLevel, lOptionName, pvOptionValue, uxOptionLength ); |
| 2973 | + break; |
| 2974 | + #endif /* (ipconfigSUPPORT_IP_MULTICAST != 0) */ |
| 2975 | + |
2932 | 2976 | default:
|
2933 | 2977 | /* No other options are handled. */
|
2934 | 2978 | xReturn = -pdFREERTOS_ERRNO_ENOPROTOOPT;
|
|
0 commit comments