|
| 1 | +/* |
| 2 | + * FreeRTOS+TCP V2.3.1 |
| 3 | + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 4 | + * |
| 5 | + * Permission is hereby granted, free of charge, to any person obtaining a copy of |
| 6 | + * this software and associated documentation files (the "Software"), to deal in |
| 7 | + * the Software without restriction, including without limitation the rights to |
| 8 | + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
| 9 | + * the Software, and to permit persons to whom the Software is furnished to do so, |
| 10 | + * subject to the following conditions: |
| 11 | + * |
| 12 | + * The above copyright notice and this permission notice shall be included in all |
| 13 | + * copies or substantial portions of the Software. |
| 14 | + * |
| 15 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
| 17 | + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
| 18 | + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
| 19 | + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 20 | + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 21 | + * |
| 22 | + * http://aws.amazon.com/freertos |
| 23 | + * http://www.FreeRTOS.org |
| 24 | + */ |
| 25 | + |
| 26 | +/* Standard includes. */ |
| 27 | +#include <stdint.h> |
| 28 | +#include <stdio.h> |
| 29 | +#include <stdlib.h> |
| 30 | + |
| 31 | +/* FreeRTOS includes. */ |
| 32 | +#include "FreeRTOS.h" |
| 33 | +#include "task.h" |
| 34 | +#include "queue.h" |
| 35 | +#include "semphr.h" |
| 36 | + |
| 37 | +/* FreeRTOS+TCP includes. */ |
| 38 | +#include "FreeRTOS_IP.h" |
| 39 | +#include "FreeRTOS_Sockets.h" |
| 40 | +#include "FreeRTOS_IP_Private.h" |
| 41 | +#include "FreeRTOS_DNS.h" |
| 42 | +#include "FreeRTOS_Routing.h" |
| 43 | +#include "FreeRTOS_ND.h" |
| 44 | +#include "NetworkBufferManagement.h" |
| 45 | +#include "NetworkInterface.h" |
| 46 | + |
| 47 | +#if ( ipconfigUSE_LOOPBACK == 0 ) |
| 48 | + #error Please define ipconfigUSE_LOOPBACK as 1 if you want to use the loop-back interface |
| 49 | +#endif |
| 50 | + |
| 51 | +#define ipICMP_ECHO_REQUEST ( ( uint8_t ) 8 ) |
| 52 | +#define ipICMP_ECHO_REPLY ( ( uint8_t ) 0 ) |
| 53 | + |
| 54 | +/*-----------------------------------------------------------*/ |
| 55 | + |
| 56 | +NetworkInterface_t * xLoopbackInterface; |
| 57 | + |
| 58 | +static BaseType_t prvLoopback_Initialise( NetworkInterface_t * pxInterface ); |
| 59 | +static BaseType_t prvLoopback_Output( NetworkInterface_t * pxInterface, |
| 60 | + NetworkBufferDescriptor_t * const pxGivenDescriptor, |
| 61 | + BaseType_t bReleaseAfterSend ); |
| 62 | +static BaseType_t prvLoopback_GetPhyLinkStatus( NetworkInterface_t * pxInterface ); |
| 63 | + |
| 64 | +NetworkInterface_t * pxLoopback_FillInterfaceDescriptor( BaseType_t xEMACIndex, |
| 65 | + NetworkInterface_t * pxInterface ); |
| 66 | + |
| 67 | +/*-----------------------------------------------------------*/ |
| 68 | + |
| 69 | +static BaseType_t prvLoopback_Initialise( NetworkInterface_t * pxInterface ) |
| 70 | +{ |
| 71 | + /* When returning non-zero, the stack will become active and |
| 72 | + * start DHCP (in configured) */ |
| 73 | + ( void ) pxInterface; |
| 74 | + return pdTRUE; |
| 75 | +} |
| 76 | +/*-----------------------------------------------------------*/ |
| 77 | + |
| 78 | +#if ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) |
| 79 | + |
| 80 | +/* Do not call the following function directly. It is there for downward compatibility. |
| 81 | + * The function FreeRTOS_IPInit() will call it to initialice the interface and end-point |
| 82 | + * objects. See the description in FreeRTOS_Routing.h. */ |
| 83 | + NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, |
| 84 | + NetworkInterface_t * pxInterface ) |
| 85 | + { |
| 86 | + pxLoopback_FillInterfaceDescriptor( xEMACIndex, pxInterface ); |
| 87 | + } |
| 88 | + |
| 89 | +#endif /* ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) */ |
| 90 | +/*-----------------------------------------------------------*/ |
| 91 | + |
| 92 | +NetworkInterface_t * pxLoopback_FillInterfaceDescriptor( BaseType_t xEMACIndex, |
| 93 | + NetworkInterface_t * pxInterface ) |
| 94 | +{ |
| 95 | +/* This function pxLoopback_FillInterfaceDescriptor() adds a network-interface. |
| 96 | + * Make sure that the object pointed to by 'pxInterface' |
| 97 | + * is declared static or global, and that it will remain to exist. */ |
| 98 | + |
| 99 | + memset( pxInterface, '\0', sizeof( *pxInterface ) ); |
| 100 | + pxInterface->pcName = "Loopback"; /* Just for logging, debugging. */ |
| 101 | + pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */ |
| 102 | + pxInterface->pfInitialise = prvLoopback_Initialise; |
| 103 | + pxInterface->pfOutput = prvLoopback_Output; |
| 104 | + pxInterface->pfGetPhyLinkStatus = prvLoopback_GetPhyLinkStatus; |
| 105 | + |
| 106 | + FreeRTOS_AddNetworkInterface( pxInterface ); |
| 107 | + xLoopbackInterface = pxInterface; |
| 108 | + |
| 109 | + return pxInterface; |
| 110 | +} |
| 111 | +/*-----------------------------------------------------------*/ |
| 112 | + |
| 113 | +static BaseType_t prvLoopback_GetPhyLinkStatus( NetworkInterface_t * pxInterface ) |
| 114 | +{ |
| 115 | + /* This function returns true if the Link Status in the PHY is high. */ |
| 116 | + ( void ) pxInterface; |
| 117 | + return pdTRUE; |
| 118 | +} |
| 119 | +/*-----------------------------------------------------------*/ |
| 120 | + |
| 121 | +static BaseType_t prvLoopback_Output( NetworkInterface_t * pxInterface, |
| 122 | + NetworkBufferDescriptor_t * const pxGivenDescriptor, |
| 123 | + BaseType_t bReleaseAfterSend ) |
| 124 | +{ |
| 125 | + NetworkBufferDescriptor_t * pxDescriptor = pxGivenDescriptor; |
| 126 | + |
| 127 | + ( void ) pxInterface; |
| 128 | + |
| 129 | + IPPacket_t * a = ( IPPacket_t * ) ( pxDescriptor->pucEthernetBuffer ); |
| 130 | + |
| 131 | + if( a->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE ) |
| 132 | + { |
| 133 | + usGenerateProtocolChecksum( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, pdTRUE ); |
| 134 | + } |
| 135 | + |
| 136 | + { |
| 137 | + MACAddress_t xMACAddress; |
| 138 | + |
| 139 | + if( pxDescriptor->pxEndPoint->bits.bIPv6 != 0 ) |
| 140 | + { |
| 141 | + #if ( ipconfigUSE_IPv6 != 0 ) |
| 142 | + if( xIsIPv6Loopback( &( pxDescriptor->xIPAddress ) ) != pdFALSE ) |
| 143 | + { |
| 144 | + vNDRefreshCacheEntry( &xMACAddress, &( pxDescriptor->xIPAddress.xIP_IPv6 ), pxDescriptor->pxEndPoint ); |
| 145 | + } |
| 146 | + #endif |
| 147 | + } |
| 148 | + else |
| 149 | + { |
| 150 | + #if ( ipconfigUSE_IPv4 != 0 ) |
| 151 | + if( xIsIPv4Loopback( pxDescriptor->xIPAddress.ulIP_IPv4 ) ) |
| 152 | + { |
| 153 | + vARPRefreshCacheEntry( &xMACAddress, pxDescriptor->xIPAddress.ulIP_IPv4, pxDescriptor->pxEndPoint ); |
| 154 | + } |
| 155 | + #endif |
| 156 | + } |
| 157 | + } |
| 158 | + |
| 159 | + if( bReleaseAfterSend == pdFALSE ) |
| 160 | + { |
| 161 | + NetworkBufferDescriptor_t * pxNewDescriptor = |
| 162 | + pxDuplicateNetworkBufferWithDescriptor( pxDescriptor, pxDescriptor->xDataLength ); |
| 163 | + pxDescriptor = pxNewDescriptor; |
| 164 | + } |
| 165 | + |
| 166 | + if( pxDescriptor != NULL ) |
| 167 | + { |
| 168 | + IPStackEvent_t xRxEvent; |
| 169 | + |
| 170 | + xRxEvent.eEventType = eNetworkRxEvent; |
| 171 | + xRxEvent.pvData = ( void * ) pxDescriptor; |
| 172 | + |
| 173 | + if( xSendEventStructToIPTask( &xRxEvent, 0u ) != pdTRUE ) |
| 174 | + { |
| 175 | + vReleaseNetworkBufferAndDescriptor( pxDescriptor ); |
| 176 | + iptraceETHERNET_RX_EVENT_LOST(); |
| 177 | + FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) ); |
| 178 | + } |
| 179 | + } |
| 180 | + |
| 181 | + /* The return value is actually ignored by the IP-stack. */ |
| 182 | + return pdTRUE; |
| 183 | +} |
| 184 | +/*-----------------------------------------------------------*/ |
0 commit comments