1 // Copyright 2018 Espressif Systems (Shanghai) PTE LTD
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 /* Standard includes. */
20 /* FreeRTOS includes. */
26 /* FreeRTOS+TCP includes. */
27 #include "FreeRTOS_IP.h"
28 #include "FreeRTOS_Sockets.h"
29 #include "FreeRTOS_IP_Private.h"
30 #include "FreeRTOS_DNS.h"
31 #include "NetworkBufferManagement.h"
32 #include "NetworkInterface.h"
36 #include "esp_wifi_internal.h"
37 #include "tcpip_adapter.h"
44 static const char *TAG = "NetInterface";
45 volatile static uint32_t xInterfaceState = INTERFACE_DOWN;
47 /* protect the function declaration itself instead of using
49 #if ( ipconfigHAS_PRINTF != 0 )
50 static void prvPrintResourceStats();
52 #define prvPrintResourceStats()
55 BaseType_t xNetworkInterfaceInitialise( void )
57 static BaseType_t xMACAdrInitialized = pdFALSE;
58 uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ];
60 if (xInterfaceState == INTERFACE_UP) {
61 if (xMACAdrInitialized == pdFALSE) {
62 esp_wifi_get_mac(ESP_IF_WIFI_STA, ucMACAddress);
63 FreeRTOS_UpdateMACAddress(ucMACAddress);
64 xMACAdrInitialized = pdTRUE;
71 BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
73 if (pxNetworkBuffer == NULL || pxNetworkBuffer->pucEthernetBuffer == NULL || pxNetworkBuffer->xDataLength == 0) {
74 ESP_LOGE(TAG, "Invalid params");
79 if (xInterfaceState == INTERFACE_DOWN) {
80 ESP_LOGD(TAG, "Interface down");
83 ret = esp_wifi_internal_tx(ESP_IF_WIFI_STA, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength);
85 ESP_LOGE(TAG, "Failed to tx buffer %p, len %d, err %d", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
89 prvPrintResourceStats();
91 if (xReleaseAfterSend == pdTRUE) {
92 vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
95 return ret == ESP_OK ? pdTRUE : pdFALSE;
98 void vNetworkNotifyIFDown()
100 IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
101 if (xInterfaceState != INTERFACE_DOWN) {
102 xInterfaceState = INTERFACE_DOWN;
103 xSendEventStructToIPTask( &xRxEvent, 0 );
107 void vNetworkNotifyIFUp()
109 xInterfaceState = INTERFACE_UP;
112 esp_err_t wlanif_input(void *netif, void *buffer, uint16_t len, void *eb)
114 NetworkBufferDescriptor_t *pxNetworkBuffer;
115 IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
116 const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
118 prvPrintResourceStats();
120 if( eConsiderFrameForProcessing( buffer ) != eProcessBuffer ) {
121 ESP_LOGD(TAG, "Dropping packet");
122 esp_wifi_internal_free_rx_buffer(eb);
126 pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(len, xDescriptorWaitTime);
127 if (pxNetworkBuffer != NULL) {
129 /* Set the packet size, in case a larger buffer was returned. */
130 pxNetworkBuffer->xDataLength = len;
132 /* Copy the packet data. */
133 memcpy(pxNetworkBuffer->pucEthernetBuffer, buffer, len);
134 xRxEvent.pvData = (void *) pxNetworkBuffer;
136 if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
137 ESP_LOGE(TAG, "Failed to enqueue packet to network stack %p, len %d", buffer, len);
138 vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
141 esp_wifi_internal_free_rx_buffer(eb);
144 ESP_LOGE(TAG, "Failed to get buffer descriptor");
149 #if ( ipconfigHAS_PRINTF != 0 )
150 static void prvPrintResourceStats()
152 static UBaseType_t uxLastMinBufferCount = 0u;
153 static UBaseType_t uxCurrentBufferCount = 0u;
154 static size_t uxMinLastSize = 0uL;
157 uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
159 if( uxLastMinBufferCount != uxCurrentBufferCount )
161 /* The logging produced below may be helpful
162 * while tuning +TCP: see how many buffers are in use. */
163 uxLastMinBufferCount = uxCurrentBufferCount;
164 FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
165 uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
168 uxMinSize = xPortGetMinimumEverFreeHeapSize();
170 if( uxMinLastSize != uxMinSize )
172 uxMinLastSize = uxMinSize;
173 FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) );
176 #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
178 static UBaseType_t uxLastMinQueueSpace = 0;
179 UBaseType_t uxCurrentCount = 0u;
181 uxCurrentCount = uxGetMinimumIPQueueSpace();
183 if( uxLastMinQueueSpace != uxCurrentCount )
185 /* The logging produced below may be helpful
186 * while tuning +TCP: see how many buffers are in use. */
187 uxLastMinQueueSpace = uxCurrentCount;
188 FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
191 #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
193 #endif /* ( ipconfigHAS_PRINTF != 0 ) */
194 /*-----------------------------------------------------------*/