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