1 // Copyright 2018 Espressif Systems (Shanghai) PTE LTD
\r
3 // Licensed under the Apache License, Version 2.0 (the "License");
\r
4 // you may not use this file except in compliance with the License.
\r
5 // You may obtain a copy of the License at
\r
7 // http://www.apache.org/licenses/LICENSE-2.0
\r
9 // Unless required by applicable law or agreed to in writing, software
\r
10 // distributed under the License is distributed on an "AS IS" BASIS,
\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
12 // See the License for the specific language governing permissions and
\r
13 // limitations under the License.
\r
15 /* Standard includes. */
\r
20 /* FreeRTOS includes. */
\r
21 #include "FreeRTOS.h"
\r
26 /* FreeRTOS+TCP includes. */
\r
27 #include "FreeRTOS_IP.h"
\r
28 #include "FreeRTOS_Sockets.h"
\r
29 #include "FreeRTOS_IP_Private.h"
\r
30 #include "FreeRTOS_DNS.h"
\r
31 #include "NetworkBufferManagement.h"
\r
32 #include "NetworkInterface.h"
\r
34 #include "esp_log.h"
\r
35 #include "esp_wifi.h"
\r
36 #include "esp_wifi_internal.h"
\r
37 #include "tcpip_adapter.h"
\r
44 static const char *TAG = "NetInterface";
\r
45 volatile static uint32_t xInterfaceState = INTERFACE_DOWN;
\r
47 #if ( ipconfigHAS_PRINTF != 0 )
\r
48 static void prvMonitorResources();
\r
51 BaseType_t xNetworkInterfaceInitialise( void )
\r
53 static BaseType_t xMACAdrInitialized = pdFALSE;
\r
54 uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ];
\r
56 if (xInterfaceState == INTERFACE_UP) {
\r
57 if (xMACAdrInitialized == pdFALSE) {
\r
58 esp_wifi_get_mac(ESP_IF_WIFI_STA, ucMACAddress);
\r
59 FreeRTOS_UpdateMACAddress(ucMACAddress);
\r
60 xMACAdrInitialized = pdTRUE;
\r
67 BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
\r
69 if (pxNetworkBuffer == NULL || pxNetworkBuffer->pucEthernetBuffer == NULL || pxNetworkBuffer->xDataLength == 0) {
\r
70 ESP_LOGE(TAG, "Invalid params");
\r
75 if (xInterfaceState == INTERFACE_DOWN) {
\r
76 ESP_LOGD(TAG, "Interface down");
\r
79 ret = esp_wifi_internal_tx(ESP_IF_WIFI_STA, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength);
\r
80 if (ret != ESP_OK) {
\r
81 ESP_LOGE(TAG, "Failed to tx buffer %p, len %d, err %d", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
\r
85 #if ( ipconfigHAS_PRINTF != 0 )
\r
86 prvMonitorResources();
\r
88 if (xReleaseAfterSend == pdTRUE) {
\r
89 vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
\r
92 return ret == ESP_OK ? pdTRUE : pdFALSE;
\r
95 void vNetworkNotifyIFDown()
\r
97 IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
\r
98 if (xInterfaceState != INTERFACE_DOWN) {
\r
99 xInterfaceState = INTERFACE_DOWN;
\r
100 xSendEventStructToIPTask( &xRxEvent, 0 );
\r
104 void vNetworkNotifyIFUp()
\r
106 xInterfaceState = INTERFACE_UP;
\r
109 esp_err_t wlanif_input(void *netif, void *buffer, uint16_t len, void *eb)
\r
111 NetworkBufferDescriptor_t *pxNetworkBuffer;
\r
112 IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
\r
113 const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
\r
115 #if ( ipconfigHAS_PRINTF != 0 )
\r
116 prvMonitorResources();
\r
119 if( eConsiderFrameForProcessing( buffer ) != eProcessBuffer ) {
\r
120 ESP_LOGD(TAG, "Dropping packet");
\r
121 esp_wifi_internal_free_rx_buffer(eb);
\r
125 pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(len, xDescriptorWaitTime);
\r
126 if (pxNetworkBuffer != NULL) {
\r
128 /* Set the packet size, in case a larger buffer was returned. */
\r
129 pxNetworkBuffer->xDataLength = len;
\r
131 /* Copy the packet data. */
\r
132 memcpy(pxNetworkBuffer->pucEthernetBuffer, buffer, len);
\r
133 xRxEvent.pvData = (void *) pxNetworkBuffer;
\r
135 if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
\r
136 ESP_LOGE(TAG, "Failed to enqueue packet to network stack %p, len %d", buffer, len);
\r
137 vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
\r
140 esp_wifi_internal_free_rx_buffer(eb);
\r
143 ESP_LOGE(TAG, "Failed to get buffer descriptor");
\r
148 #if ( ipconfigHAS_PRINTF != 0 )
\r
149 static void prvMonitorResources()
\r
151 static UBaseType_t uxLastMinBufferCount = 0u;
\r
152 static UBaseType_t uxCurrentBufferCount = 0u;
\r
153 static size_t uxMinLastSize = 0uL;
\r
156 uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
\r
158 if( uxLastMinBufferCount != uxCurrentBufferCount )
\r
160 /* The logging produced below may be helpful
\r
161 * while tuning +TCP: see how many buffers are in use. */
\r
162 uxLastMinBufferCount = uxCurrentBufferCount;
\r
163 FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
\r
164 uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
\r
167 uxMinSize = xPortGetMinimumEverFreeHeapSize();
\r
169 if( uxMinLastSize != uxMinSize )
\r
171 uxMinLastSize = uxMinSize;
\r
172 FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) );
\r
175 #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
\r
177 static UBaseType_t uxLastMinQueueSpace = 0;
\r
178 UBaseType_t uxCurrentCount = 0u;
\r
180 uxCurrentCount = uxGetMinimumIPQueueSpace();
\r
182 if( uxLastMinQueueSpace != uxCurrentCount )
\r
184 /* The logging produced below may be helpful
\r
185 * while tuning +TCP: see how many buffers are in use. */
\r
186 uxLastMinQueueSpace = uxCurrentCount;
\r
187 FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
\r
190 #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
\r
192 #endif /* ( ipconfigHAS_PRINTF != 0 ) */
\r
193 /*-----------------------------------------------------------*/
\r