]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c
96503f457a504e1a60728826b19f0e18edc0d2fe
[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 BaseType_t xNetworkInterfaceInitialise( void )
48 {
49     static BaseType_t xMACAdrInitialized = pdFALSE;
50     uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ];
51
52     if (xInterfaceState == INTERFACE_UP) {
53         if (xMACAdrInitialized == pdFALSE) {
54             esp_wifi_get_mac(ESP_IF_WIFI_STA, ucMACAddress);
55             FreeRTOS_UpdateMACAddress(ucMACAddress);
56             xMACAdrInitialized = pdTRUE;
57         }
58         return pdTRUE;
59     }
60     return pdFALSE;
61 }
62
63 BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
64 {
65     if (pxNetworkBuffer == NULL || pxNetworkBuffer->pucEthernetBuffer == NULL || pxNetworkBuffer->xDataLength == 0) {
66         ESP_LOGE(TAG, "Invalid params");
67         return pdFALSE;
68     }
69
70     esp_err_t ret;
71     if (xInterfaceState == INTERFACE_DOWN) {
72         ESP_LOGD(TAG, "Interface down");
73         ret = ESP_FAIL;
74     } else {
75         ret = esp_wifi_internal_tx(ESP_IF_WIFI_STA, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength);
76         if (ret != ESP_OK) {
77             ESP_LOGE(TAG, "Failed to tx buffer %p, len %d, err %d", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
78         }
79     }
80
81     if (xReleaseAfterSend == pdTRUE) {
82         vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
83     }
84
85     return ret == ESP_OK ? pdTRUE : pdFALSE;
86 }
87
88 void vNetworkNotifyIFDown()
89 {
90     IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
91     if (xInterfaceState != INTERFACE_DOWN) {
92         xInterfaceState = INTERFACE_DOWN;
93         xSendEventStructToIPTask( &xRxEvent, 0 );
94     }
95 }
96
97 void vNetworkNotifyIFUp()
98 {
99     xInterfaceState = INTERFACE_UP;
100 }
101
102 esp_err_t wlanif_input(void *netif, void *buffer, uint16_t len, void *eb)
103 {
104     NetworkBufferDescriptor_t *pxNetworkBuffer;
105     IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
106     const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
107
108     if( eConsiderFrameForProcessing( buffer ) != eProcessBuffer ) {
109         ESP_LOGD(TAG, "Dropping packet");
110         esp_wifi_internal_free_rx_buffer(eb);
111         return ESP_OK;
112     }
113
114     pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(len, xDescriptorWaitTime);
115     if (pxNetworkBuffer != NULL) {
116
117         /* Set the packet size, in case a larger buffer was returned. */
118         pxNetworkBuffer->xDataLength = len;
119
120         /* Copy the packet data. */
121         memcpy(pxNetworkBuffer->pucEthernetBuffer, buffer, len);
122         xRxEvent.pvData = (void *) pxNetworkBuffer;
123
124         if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
125             ESP_LOGE(TAG, "Failed to enqueue packet to network stack %p, len %d", buffer, len);
126             vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
127             return ESP_FAIL;
128         }
129         esp_wifi_internal_free_rx_buffer(eb);
130         return ESP_OK;
131     } else {
132         ESP_LOGE(TAG, "Failed to get buffer descriptor");
133         return ESP_FAIL;
134     }
135 }