|
59 | 59 | #include "FreeRTOS_DNS.h"
|
60 | 60 | #include "FreeRTOS_Routing.h"
|
61 | 61 | #include "FreeRTOS_ND.h"
|
| 62 | +#if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) ) |
| 63 | + #include "FreeRTOS_IGMP.h" |
| 64 | +#endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */ |
62 | 65 |
|
63 | 66 | /** @brief Time delay between repeated attempts to initialise the network hardware. */
|
64 | 67 | #ifndef ipINITIALISATION_RETRY_DELAY
|
@@ -460,6 +463,20 @@ static void prvProcessIPEventsAndTimers( void )
|
460 | 463 | /* xQueueReceive() returned because of a normal time-out. */
|
461 | 464 | break;
|
462 | 465 |
|
| 466 | + #if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) ) |
| 467 | + case eSocketOptAddMembership: |
| 468 | + case eSocketOptDropMembership: |
| 469 | + { |
| 470 | + MulticastAction_t * pxMCA = ( MulticastAction_t * ) xReceivedEvent.pvData; |
| 471 | + vModifyMulticastMembership( pxMCA, xReceivedEvent.eEventType ); |
| 472 | + break; |
| 473 | + } |
| 474 | + |
| 475 | + case eMulticastTimerEvent: |
| 476 | + vIPMulticast_HandleTimerEvent(); |
| 477 | + break; |
| 478 | + #endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */ |
| 479 | + |
463 | 480 | default:
|
464 | 481 | /* Should not get here. */
|
465 | 482 | break;
|
@@ -519,6 +536,11 @@ static void prvIPTask_Initialise( void )
|
519 | 536 | }
|
520 | 537 | #endif /* ( ( ipconfigUSE_DNS_CACHE != 0 ) && ( ipconfigUSE_DNS != 0 ) ) */
|
521 | 538 |
|
| 539 | + /* Init the list that will hold scheduled IGMP reports. */ |
| 540 | + #if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) ) |
| 541 | + ( void ) vIPMulticast_Init(); |
| 542 | + #endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */ |
| 543 | + |
522 | 544 | /* Initialisation is complete and events can now be processed. */
|
523 | 545 | xIPTaskInitialised = pdTRUE;
|
524 | 546 | }
|
@@ -632,6 +654,16 @@ void vIPNetworkUpCalls( struct xNetworkEndPoint * pxEndPoint )
|
632 | 654 | #endif
|
633 | 655 | }
|
634 | 656 |
|
| 657 | + #if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) ) |
| 658 | + |
| 659 | + /* Reschedule all multicast reports associated with this end-point. |
| 660 | + * Note: countdown is in increments of ipIGMP_TIMER_PERIOD_MS. It's a good idea to spread out all reports a little. |
| 661 | + * 200 to 500ms ( xMaxCountdown of 2 - 5 ) should be a good happy medium. If the network we just connected to has a IGMP/MLD querier, |
| 662 | + * they will soon ask us for reports anyways, so sending these unsolicited reports is not required. It simply enhances the user |
| 663 | + * experience by shortening the time it takes before we begin receiving the multicasts that we care for. */ |
| 664 | + vRescheduleAllMulticastReports( pxEndPoint->pxNetworkInterface, 5 ); |
| 665 | + #endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */ |
| 666 | + |
635 | 667 | pxEndPoint->bits.bEndPointUp = pdTRUE_UNSIGNED;
|
636 | 668 |
|
637 | 669 | #if ( ipconfigUSE_NETWORK_EVENT_HOOK == 1 )
|
@@ -1321,6 +1353,7 @@ void FreeRTOS_ReleaseUDPPayloadBuffer( void const * pvBuffer )
|
1321 | 1353 | pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ] = FREERTOS_SO_UDPCKSUM_OUT;
|
1322 | 1354 | pxNetworkBuffer->xIPAddress.ulIP_IPv4 = ulIPAddress;
|
1323 | 1355 | pxNetworkBuffer->usPort = ipPACKET_CONTAINS_ICMP_DATA;
|
| 1356 | + pxNetworkBuffer->ucMaximumHops = ipconfigICMP_TIME_TO_LIVE; |
1324 | 1357 | /* xDataLength is the size of the total packet, including the Ethernet header. */
|
1325 | 1358 | pxNetworkBuffer->xDataLength = uxTotalLength;
|
1326 | 1359 |
|
@@ -1477,34 +1510,50 @@ eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucE
|
1477 | 1510 | /* The packet was directed to this node - process it. */
|
1478 | 1511 | eReturn = eProcessBuffer;
|
1479 | 1512 | }
|
1480 |
| - else if( memcmp( xBroadcastMACAddress.ucBytes, pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 ) |
1481 |
| - { |
1482 |
| - /* The packet was a broadcast - process it. */ |
1483 |
| - eReturn = eProcessBuffer; |
1484 |
| - } |
1485 |
| - else |
1486 |
| - #if ( ( ipconfigUSE_LLMNR == 1 ) && ( ipconfigUSE_DNS != 0 ) ) |
1487 |
| - if( memcmp( xLLMNR_MacAddress.ucBytes, pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 ) |
| 1513 | + |
| 1514 | + #if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) ) |
| 1515 | + |
| 1516 | + /* |
| 1517 | + * With ipconfigSUPPORT_IP_MULTICAST enabled, FreeRTOS+TCP needs access to all |
| 1518 | + * multicast packets. It is too early to filter them out here because we don't |
| 1519 | + * know which socket needs which multicast address. Another thing to consider is |
| 1520 | + * that unless this function returns eProcessBuffer, eApplicationProcessCustomFrameHook() |
| 1521 | + * will not be called, so handling custom multicast frames would be impossible. |
| 1522 | + * Note that the broadcast MAC is a type of multicast so the multicast check covers it. |
| 1523 | + */ |
| 1524 | + else if( MAC_IS_MULTICAST( pxEthernetHeader->xDestinationAddress.ucBytes ) ) |
1488 | 1525 | {
|
1489 |
| - /* The packet is a request for LLMNR - process it. */ |
1490 | 1526 | eReturn = eProcessBuffer;
|
1491 | 1527 | }
|
1492 |
| - else |
1493 |
| - #endif /* ipconfigUSE_LLMNR */ |
1494 |
| - #if ( ( ipconfigUSE_MDNS == 1 ) && ( ipconfigUSE_DNS != 0 ) ) |
1495 |
| - if( memcmp( xMDNS_MacAddress.ucBytes, pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 ) |
| 1528 | + #else /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */ |
| 1529 | + else if( memcmp( xBroadcastMACAddress.ucBytes, pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 ) |
1496 | 1530 | {
|
1497 |
| - /* The packet is a request for MDNS - process it. */ |
| 1531 | + /* The packet was a broadcast - process it. */ |
1498 | 1532 | eReturn = eProcessBuffer;
|
1499 | 1533 | }
|
1500 |
| - else |
1501 |
| - #endif /* ipconfigUSE_MDNS */ |
1502 |
| - if( ( pxEthernetHeader->xDestinationAddress.ucBytes[ 0 ] == ipMULTICAST_MAC_ADDRESS_IPv6_0 ) && |
1503 |
| - ( pxEthernetHeader->xDestinationAddress.ucBytes[ 1 ] == ipMULTICAST_MAC_ADDRESS_IPv6_1 ) ) |
1504 |
| - { |
1505 |
| - /* The packet is a request for LLMNR - process it. */ |
1506 |
| - eReturn = eProcessBuffer; |
1507 |
| - } |
| 1534 | + #if ( ( ipconfigUSE_LLMNR == 1 ) && ( ipconfigUSE_DNS != 0 ) ) |
| 1535 | + else if( memcmp( xLLMNR_MacAddress.ucBytes, pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 ) |
| 1536 | + { |
| 1537 | + /* The packet is a request for LLMNR - process it. */ |
| 1538 | + eReturn = eProcessBuffer; |
| 1539 | + } |
| 1540 | + #endif /* ipconfigUSE_LLMNR */ |
| 1541 | + #if ( ( ipconfigUSE_MDNS == 1 ) && ( ipconfigUSE_DNS != 0 ) ) |
| 1542 | + else if( memcmp( xMDNS_MacAddress.ucBytes, pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 ) |
| 1543 | + { |
| 1544 | + /* The packet is a request for MDNS - process it. */ |
| 1545 | + eReturn = eProcessBuffer; |
| 1546 | + } |
| 1547 | + #endif /* ipconfigUSE_MDNS */ |
| 1548 | + #if ( ipconfigIS_ENABLED( ipconfigUSE_IPv6 ) ) |
| 1549 | + else if( ( pxEthernetHeader->xDestinationAddress.ucBytes[ 0 ] == ipMULTICAST_MAC_ADDRESS_IPv6_0 ) && |
| 1550 | + ( pxEthernetHeader->xDestinationAddress.ucBytes[ 1 ] == ipMULTICAST_MAC_ADDRESS_IPv6_1 ) ) |
| 1551 | + { |
| 1552 | + /* The packet is an IPv6 multicast - process it. */ |
| 1553 | + eReturn = eProcessBuffer; |
| 1554 | + } |
| 1555 | + #endif /* ipconfigIS_ENABLED( ipconfigUSE_IPv6 ) */ |
| 1556 | + #endif /* ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) */ |
1508 | 1557 | else
|
1509 | 1558 | {
|
1510 | 1559 | /* The packet was not a broadcast, or for this node, just release
|
@@ -2009,6 +2058,13 @@ static eFrameProcessingResult_t prvProcessIPPacket( const IPPacket_t * pxIPPacke
|
2009 | 2058 | break;
|
2010 | 2059 | #endif /* ( ipconfigUSE_IPv6 != 0 ) */
|
2011 | 2060 |
|
| 2061 | + #if ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) && ipconfigIS_ENABLED( ipconfigUSE_IPv4 ) ) |
| 2062 | + case ipPROTOCOL_IGMP: |
| 2063 | + /* The IP packet contained an IGMP frame. */ |
| 2064 | + eReturn = eProcessIGMPPacket( pxNetworkBuffer ); |
| 2065 | + break; |
| 2066 | + #endif /* ( ipconfigIS_ENABLED( ipconfigSUPPORT_IP_MULTICAST ) && ipconfigIS_ENABLED( ipconfigUSE_IPv4 ) ) */ |
| 2067 | + |
2012 | 2068 | case ipPROTOCOL_UDP:
|
2013 | 2069 | /* The IP packet contained a UDP frame. */
|
2014 | 2070 |
|
|
0 commit comments