1
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
39
49
50
54
55
64
65
66
84
85
86
87
88
89
90
91
92
96
97
98
102
103
104
105
106
109
110
111
112
129
130
131
132
137
138
139
140
141
142
143
146
147
148
149
150
151
152
153
154
155
160
161
162
163
167
168
169
170
171
172
173
174
175
176
177
178
179
181
182
183
184
185
186
187
188
189
190
200
201
202
209
210
211
212
/* ... */
#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;
/* ... */
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) {
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;
}{ ... }
/* ... */
#define GPIO_INPUT CONFIG_EXAMPLE_RECONFIGURE_BUTTON
#define GPIO_LONG_PUSH_US 2000000
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);
gpio_isr_handler_add(GPIO_INPUT, gpio_isr_handler, NULL);
}{ ... }
/* ... */
void app_main(void)
{
static __NOINIT_ATTR uint32_t s_reconfigure_requested;
static const uint32_t RECONFIGURE_REQUEST = 0x1C55AA;
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;
}{...}
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));
s_event_flags = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_create_default());
gpio_init();
esp_read_mac(s_sta_mac, ESP_MAC_WIFI_STA);
/* ... */
if (do_provision || !is_provisioned()) {
ESP_LOGI(TAG, "Starting provisioning");
ESP_ERROR_CHECK(esp_netif_init());
esp_netif_create_default_wifi_sta();
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) {
xEventGroupSetBits(s_event_flags, RECONFIGURE_BIT);
}{...} else {
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) {
s_reconfigure_requested = RECONFIGURE_REQUEST;
}{...} else {
s_reconfigure_requested = 0;
}{...}
vTaskDelay(pdMS_TO_TICKS(1000));
esp_restart();
}{ ... }