Select one of the symbols to view example projects that use it.
 
Outline
#include <string.h>
#include <esp_timer.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_mac.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_private/wifi.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "provisioning.h"
#include "wired_iface.h"
TAG
s_event_flags
s_wifi_is_connected
s_sta_mac
CONNECTED_BIT
DISCONNECTED_BIT
RECONFIGURE_BIT
PROV_SUCCESS_BIT
PROV_FAIL_BIT
wired_recv_callback(void *, uint16_t, void *)
wifi_buff_free(void *, void *)
wifi_recv_callback(void *, uint16_t, void *)
event_handler(void *, esp_event_base_t, int32_t, void *)
connect_wifi()
#define GPIO_INPUT
#define GPIO_LONG_PUSH_US
gpio_isr_handler(void *)
gpio_init()
app_main()
Files
loading (3/5)...
SourceVuESP-IDF Framework and Examplessta2eth samplemain/sta2eth_main.c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 *//* ... */ #include <string.h> #include <esp_timer.h> #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" #include "esp_log.h" #include "esp_wifi.h" #include "esp_mac.h" #include "esp_netif.h" #include "esp_event.h" #include "esp_private/wifi.h" #include "nvs_flash.h" #include "driver/gpio.h" #include "provisioning.h" #include "wired_iface.h"14 includes static const char *TAG = "example_sta2wired"; static EventGroupHandle_t s_event_flags; static bool s_wifi_is_connected = false; static uint8_t s_sta_mac[6]; const int CONNECTED_BIT = BIT0; const int DISCONNECTED_BIT = BIT1; const int RECONFIGURE_BIT = BIT2; const int PROV_SUCCESS_BIT = BIT3; const int PROV_FAIL_BIT = BIT4; /** * WiFi -- Wired packet path *//* ... */ static esp_err_t wired_recv_callback(void *buffer, uint16_t len, void *ctx) { if (s_wifi_is_connected) { mac_spoof(FROM_WIRED, buffer, len, s_sta_mac); if (esp_wifi_internal_tx(ESP_IF_WIFI_STA, buffer, len) != ESP_OK) { ESP_LOGD(TAG, "Failed to send packet to WiFi!"); }{...} }{...} return ESP_OK; }{ ... } static void wifi_buff_free(void *buffer, void *ctx) { esp_wifi_internal_free_rx_buffer(buffer); }{ ... } static esp_err_t wifi_recv_callback(void *buffer, uint16_t len, void *eb) { mac_spoof(TO_WIRED, buffer, len, s_sta_mac); if (wired_send(buffer, len, eb) != ESP_OK) { esp_wifi_internal_free_rx_buffer(eb); ESP_LOGD(TAG, "Failed to send packet to USB!"); }{...} return ESP_OK; }{ ... } static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { ESP_LOGI(TAG, "Wi-Fi STA disconnected"); s_wifi_is_connected = false; esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, NULL); esp_wifi_connect(); xEventGroupClearBits(s_event_flags, CONNECTED_BIT); xEventGroupSetBits(s_event_flags, DISCONNECTED_BIT); }{...} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) { ESP_LOGI(TAG, "Wi-Fi STA connected"); esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, wifi_recv_callback); s_wifi_is_connected = true; xEventGroupClearBits(s_event_flags, DISCONNECTED_BIT); xEventGroupSetBits(s_event_flags, CONNECTED_BIT); }{...} }{ ... } static esp_err_t connect_wifi(void) { ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL)); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); ESP_ERROR_CHECK(esp_wifi_start() ); wifi_config_t wifi_cfg; if (esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) { // configuration not available, report error to restart provisioning return ESP_FAIL; }{...} esp_wifi_connect(); EventBits_t status = xEventGroupWaitBits(s_event_flags, CONNECTED_BIT, 0, 1, 10000 / portTICK_PERIOD_MS); if (status & CONNECTED_BIT) { ESP_LOGI(TAG, "WiFi station connected successfully"); return ESP_OK; }{...} ESP_LOGE(TAG, "WiFi station connected failed"); return ESP_ERR_TIMEOUT; }{ ... } /** * GPIO button functionality *//* ... */ #define GPIO_INPUT CONFIG_EXAMPLE_RECONFIGURE_BUTTON #define GPIO_LONG_PUSH_US 2000000 /* push for 2 seconds to reconfigure */ static void IRAM_ATTR gpio_isr_handler(void *arg) { static int64_t last_pushed = -1; if (gpio_get_level(GPIO_INPUT) == 0) { last_pushed = esp_timer_get_time(); }{...} else { uint64_t now = esp_timer_get_time(); if (last_pushed != -1 && now - last_pushed > GPIO_LONG_PUSH_US) { BaseType_t high_task_wakeup; xEventGroupSetBitsFromISR(s_event_flags, RECONFIGURE_BIT, &high_task_wakeup); if (high_task_wakeup) { portYIELD_FROM_ISR(); }{...} }{...} last_pushed = -1; }{...} }{ ... } static void gpio_init(void) { gpio_config_t io_conf = { .intr_type = GPIO_INTR_ANYEDGE, .pin_bit_mask = (1ULL << GPIO_INPUT), .mode = GPIO_MODE_INPUT, .pull_up_en = 1 }{...}; gpio_config(&io_conf); gpio_install_isr_service(0); //hook isr handler for specific gpio pin gpio_isr_handler_add(GPIO_INPUT, gpio_isr_handler, NULL); }{ ... } /** * Application *//* ... */ void app_main(void) { static __NOINIT_ATTR uint32_t s_reconfigure_requested; static const uint32_t RECONFIGURE_REQUEST = 0x1C55AA; /* Check reset reason and decide if we should re-provision */ bool do_provision = false; esp_reset_reason_t reason = esp_reset_reason(); ESP_LOGD(TAG, "After restart! %d", reason); if (reason != ESP_RST_SW) { s_reconfigure_requested = 0; }{...} else if (s_reconfigure_requested == RECONFIGURE_REQUEST) { do_provision = true; }{...} /* Initialize NVS and WiFi */ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); }{...} ESP_ERROR_CHECK(ret); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); // init the flags and event loop s_event_flags = xEventGroupCreate(); ESP_ERROR_CHECK(esp_event_loop_create_default()); /* Init the re-provisioning button (long-press with initiate provisioning restart) */ gpio_init(); esp_read_mac(s_sta_mac, ESP_MAC_WIFI_STA); /* Start the application in configuration mode (to perform provisioning) * or in a bridge mode (already provisioned) *//* ... */ if (do_provision || !is_provisioned()) { ESP_LOGI(TAG, "Starting provisioning"); ESP_ERROR_CHECK(esp_netif_init()); // needed to complete provisioning with getting a valid IP event esp_netif_create_default_wifi_sta(); // starts the wired interface with virtual network used to configure/provision the example wired_netif_init(); start_provisioning(&s_event_flags, PROV_SUCCESS_BIT, PROV_FAIL_BIT); }{...} else { ESP_LOGI(TAG, "Starting USB-WiFi bridge"); if (connect_wifi() != ESP_OK) { // if we cannot connect to WiFi we just try to re-provision xEventGroupSetBits(s_event_flags, RECONFIGURE_BIT); }{...} else { // start the wired interface in the bridge mode wired_bridge_init(wired_recv_callback, wifi_buff_free); }{...} }{...} EventBits_t bits = xEventGroupWaitBits(s_event_flags, RECONFIGURE_BIT | PROV_SUCCESS_BIT | PROV_FAIL_BIT, pdTRUE, pdFALSE, portMAX_DELAY); if (bits & RECONFIGURE_BIT || bits & PROV_FAIL_BIT) { // retry provisioning if it previously failed or if requested by the button press s_reconfigure_requested = RECONFIGURE_REQUEST; }{...} else { // provisioning successfully finished, restart to the bridge mode s_reconfigure_requested = 0; }{...} vTaskDelay(pdMS_TO_TICKS(1000)); // to let httpd handle the closure esp_restart(); }{ ... }
Details
Show:
from
Types: Columns:
This file uses the notable symbols shown below. Click anywhere in the file to view more details.