]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / esp32 / NetworkInterface.c
1 // Copyright 2018 Espressif Systems (Shanghai) PTE LTD
2 //
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
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14
15 /* Standard includes. */
16 #include <stdint.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19
20 /* FreeRTOS includes. */
21 #include "FreeRTOS.h"
22 #include "task.h"
23 #include "queue.h"
24 #include "semphr.h"
25
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"
33
34 #include "esp_log.h"
35 #include "esp_wifi.h"
36 #include "esp_wifi_internal.h"
37 #include "tcpip_adapter.h"
38
39 enum if_state_t {
40     INTERFACE_DOWN = 0,
41     INTERFACE_UP,
42 };
43
44 static const char *TAG = "NetInterface";
45 volatile static uint32_t xInterfaceState = INTERFACE_DOWN;
46
47 /* protect the function declaration itself instead of using
48    #if everywhere.                                        */
49 #if ( ipconfigHAS_PRINTF != 0 )
50     static void prvPrintResourceStats();    
51 #else
52     #define prvPrintResourceStats()
53 #endif
54
55 BaseType_t xNetworkInterfaceInitialise( void )
56 {
57     static BaseType_t xMACAdrInitialized = pdFALSE;
58     uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ];
59
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;
65         }
66         return pdTRUE;
67     }
68     return pdFALSE;
69 }
70
71 BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
72 {
73     if (pxNetworkBuffer == NULL || pxNetworkBuffer->pucEthernetBuffer == NULL || pxNetworkBuffer->xDataLength == 0) {
74         ESP_LOGE(TAG, "Invalid params");
75         return pdFALSE;
76     }
77
78     esp_err_t ret;
79     if (xInterfaceState == INTERFACE_DOWN) {
80         ESP_LOGD(TAG, "Interface down");
81         ret = ESP_FAIL;
82     } else {
83         ret = esp_wifi_internal_tx(ESP_IF_WIFI_STA, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength);
84         if (ret != ESP_OK) {
85             ESP_LOGE(TAG, "Failed to tx buffer %p, len %d, err %d", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
86         }
87     }
88
89     prvPrintResourceStats();
90     
91     if (xReleaseAfterSend == pdTRUE) {
92         vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
93     }
94
95     return ret == ESP_OK ? pdTRUE : pdFALSE;
96 }
97
98 void vNetworkNotifyIFDown()
99 {
100     IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
101     if (xInterfaceState != INTERFACE_DOWN) {
102         xInterfaceState = INTERFACE_DOWN;
103         xSendEventStructToIPTask( &xRxEvent, 0 );
104     }
105 }
106
107 void vNetworkNotifyIFUp()
108 {
109     xInterfaceState = INTERFACE_UP;
110 }
111
112 esp_err_t wlanif_input(void *netif, void *buffer, uint16_t len, void *eb)
113 {
114     NetworkBufferDescriptor_t *pxNetworkBuffer;
115     IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
116     const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
117
118     prvPrintResourceStats();
119
120     if( eConsiderFrameForProcessing( buffer ) != eProcessBuffer ) {
121         ESP_LOGD(TAG, "Dropping packet");
122         esp_wifi_internal_free_rx_buffer(eb);
123         return ESP_OK;
124     }
125
126     pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(len, xDescriptorWaitTime);
127     if (pxNetworkBuffer != NULL) {
128
129         /* Set the packet size, in case a larger buffer was returned. */
130         pxNetworkBuffer->xDataLength = len;
131
132         /* Copy the packet data. */
133         memcpy(pxNetworkBuffer->pucEthernetBuffer, buffer, len);
134         xRxEvent.pvData = (void *) pxNetworkBuffer;
135
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);
139             return ESP_FAIL;
140         }
141         esp_wifi_internal_free_rx_buffer(eb);
142         return ESP_OK;
143     } else {
144         ESP_LOGE(TAG, "Failed to get buffer descriptor");
145         return ESP_FAIL;
146     }
147 }
148
149 #if ( ipconfigHAS_PRINTF != 0 )
150     static void prvPrintResourceStats()
151     {
152         static UBaseType_t uxLastMinBufferCount = 0u;
153         static UBaseType_t uxCurrentBufferCount = 0u;
154         static size_t uxMinLastSize = 0uL;
155         size_t uxMinSize;
156
157         uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
158
159         if( uxLastMinBufferCount != uxCurrentBufferCount )
160         {
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 ) );
166         }
167
168         uxMinSize = xPortGetMinimumEverFreeHeapSize();
169
170         if( uxMinLastSize != uxMinSize )
171         {
172             uxMinLastSize = uxMinSize;
173             FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) );
174         }
175
176         #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
177             {
178                 static UBaseType_t uxLastMinQueueSpace = 0;
179                 UBaseType_t uxCurrentCount = 0u;
180
181                 uxCurrentCount = uxGetMinimumIPQueueSpace();
182
183                 if( uxLastMinQueueSpace != uxCurrentCount )
184                 {
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 ) );
189                 }
190             }
191         #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
192     }
193 #endif /* ( ipconfigHAS_PRINTF != 0 ) */
194 /*-----------------------------------------------------------*/