2022-12-28 23:58:02 -05:00
|
|
|
/*
|
2022-11-07 09:10:22 -05:00
|
|
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
2022-12-28 23:58:02 -05:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
|
|
|
*/
|
2022-12-20 09:07:54 -05:00
|
|
|
/* itwt Example
|
|
|
|
|
|
|
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, this
|
|
|
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
|
|
CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
this example shows how to use itwt
|
|
|
|
set a router or a AP using the same SSID&PASSWORD as configuration of this example.
|
|
|
|
start esp32c6 and when it connected to AP it will setup itwt.
|
|
|
|
*/
|
2023-04-05 22:46:32 -04:00
|
|
|
#include <netdb.h>
|
2022-12-20 09:07:54 -05:00
|
|
|
#include "freertos/FreeRTOS.h"
|
|
|
|
#include "freertos/event_groups.h"
|
|
|
|
#include "esp_wifi.h"
|
|
|
|
#include "esp_log.h"
|
|
|
|
#include "esp_event.h"
|
|
|
|
#include "nvs_flash.h"
|
|
|
|
#include "esp_console.h"
|
|
|
|
#include "cmd_system.h"
|
|
|
|
#include "wifi_cmd.h"
|
|
|
|
#include "esp_wifi_he.h"
|
2022-11-07 09:10:22 -05:00
|
|
|
#include "esp_pm.h"
|
2023-04-05 22:46:32 -04:00
|
|
|
#include "esp_timer.h"
|
2022-12-20 09:07:54 -05:00
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
* Constants
|
|
|
|
*******************************************************/
|
|
|
|
static const char *TAG = "itwt";
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
* Structures
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
* Variable Definitions
|
|
|
|
*******************************************************/
|
|
|
|
/*set the ssid and password via "idf.py menuconfig"*/
|
|
|
|
#define DEFAULT_SSID CONFIG_EXAMPLE_WIFI_SSID
|
|
|
|
#define DEFAULT_PWD CONFIG_EXAMPLE_WIFI_PASSWORD
|
|
|
|
|
|
|
|
#if CONFIG_EXAMPLE_ITWT_TRIGGER_ENABLE
|
|
|
|
bool trigger_enabled = true;
|
|
|
|
#else
|
|
|
|
bool trigger_enabled = false;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if CONFIG_EXAMPLE_ITWT_ANNOUNCED
|
|
|
|
bool flow_type_announced = true;
|
|
|
|
#else
|
|
|
|
bool flow_type_announced = false;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
esp_netif_t *netif_sta = NULL;
|
|
|
|
const int CONNECTED_BIT = BIT0;
|
|
|
|
const int DISCONNECTED_BIT = BIT1;
|
|
|
|
EventGroupHandle_t wifi_event_group;
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
* Function Declarations
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
* Function Definitions
|
|
|
|
*******************************************************/
|
2023-04-05 22:46:32 -04:00
|
|
|
|
|
|
|
static void example_set_static_ip(esp_netif_t *netif)
|
|
|
|
{
|
|
|
|
#if CONFIG_EXAMPLE_ENABLE_STATIC_IP
|
|
|
|
if (esp_netif_dhcpc_stop(netif) != ESP_OK) {
|
|
|
|
ESP_LOGE(TAG, "Failed to stop dhcp client");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
esp_netif_ip_info_t ip;
|
|
|
|
memset(&ip, 0 , sizeof(esp_netif_ip_info_t));
|
|
|
|
ip.ip.addr = ipaddr_addr(CONFIG_EXAMPLE_STATIC_IP_ADDR);
|
|
|
|
ip.netmask.addr = ipaddr_addr(CONFIG_EXAMPLE_STATIC_NETMASK_ADDR);
|
|
|
|
ip.gw.addr = ipaddr_addr(CONFIG_EXAMPLE_STATIC_GW_ADDR);
|
|
|
|
if (esp_netif_set_ip_info(netif, &ip) != ESP_OK) {
|
|
|
|
ESP_LOGE(TAG, "Failed to set ip info");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ESP_LOGI(TAG, "Success to set static ip: %s, netmask: %s, gw: %s",
|
|
|
|
CONFIG_EXAMPLE_STATIC_IP_ADDR, CONFIG_EXAMPLE_STATIC_NETMASK_ADDR, CONFIG_EXAMPLE_STATIC_GW_ADDR);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2022-12-20 09:07:54 -05:00
|
|
|
static const char *itwt_probe_status_to_str(wifi_itwt_probe_status_t status)
|
|
|
|
{
|
|
|
|
switch (status) {
|
|
|
|
case ITWT_PROBE_FAIL: return "itwt probe fail";
|
|
|
|
case ITWT_PROBE_SUCCESS: return "itwt probe success";
|
|
|
|
case ITWT_PROBE_TIMEOUT: return "itwt probe timeout";
|
|
|
|
case ITWT_PROBE_STA_DISCONNECTED: return "Sta disconnected";
|
|
|
|
default: return "Unknown status";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void got_ip_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
int32_t event_id, void *event_data)
|
|
|
|
{
|
|
|
|
xEventGroupClearBits(wifi_event_group, DISCONNECTED_BIT);
|
|
|
|
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
|
|
|
|
|
|
|
/* setup a trigger-based announce individual TWT agreement. */
|
2023-02-16 00:59:36 -05:00
|
|
|
wifi_phy_mode_t phymode;
|
2022-12-20 09:07:54 -05:00
|
|
|
wifi_config_t sta_cfg = { 0, };
|
|
|
|
esp_wifi_get_config(WIFI_IF_STA, &sta_cfg);
|
2023-02-16 00:59:36 -05:00
|
|
|
esp_wifi_sta_get_negotiated_phymode(&phymode);
|
|
|
|
if (phymode == WIFI_PHY_MODE_HE20) {
|
2023-04-05 22:46:32 -04:00
|
|
|
esp_err_t err = ESP_OK;
|
|
|
|
int flow_id = 0;
|
2022-12-20 09:07:54 -05:00
|
|
|
err = esp_wifi_sta_itwt_setup(TWT_REQUEST, trigger_enabled, flow_type_announced ? 0 : 1,
|
|
|
|
CONFIG_EXAMPLE_ITWT_MIN_WAKE_DURA, CONFIG_EXAMPLE_ITWT_WAKE_INVL_EXPN,
|
|
|
|
CONFIG_EXAMPLE_ITWT_WAKE_INVL_MANT, &flow_id);
|
|
|
|
if (err != ESP_OK) {
|
|
|
|
ESP_LOGE(TAG, "itwt setup failed, err:0x%x", err);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "Must be in 11ax mode to support itwt");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void connect_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
int32_t event_id, void *event_data)
|
|
|
|
{
|
|
|
|
ESP_LOGI(TAG, "sta connect to %s", DEFAULT_SSID);
|
|
|
|
esp_wifi_connect();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void disconnect_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
int32_t event_id, void *event_data)
|
|
|
|
{
|
|
|
|
ESP_LOGI(TAG, "sta disconnect, reconnect...");
|
|
|
|
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
|
|
|
esp_wifi_connect();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void itwt_setup_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
int32_t event_id, void *event_data)
|
|
|
|
{
|
|
|
|
wifi_event_sta_itwt_setup_t *setup = (wifi_event_sta_itwt_setup_t *) event_data;
|
|
|
|
if (setup->setup_cmd == TWT_ACCEPT) {
|
|
|
|
/* TWT Wake Interval = TWT Wake Interval Mantissa * (2 ^ TWT Wake Interval Exponent) */
|
|
|
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>flow_id:%d, %s, %s, wake_dura:%d, wake_invl_e:%d, wake_invl_m:%d", setup->flow_id,
|
|
|
|
setup->trigger ? "trigger-enabled" : "non-trigger-enabled", setup->flow_type ? "unannounced" : "announced",
|
|
|
|
setup->min_wake_dura, setup->wake_invl_expn, setup->wake_invl_mant);
|
2023-04-05 22:46:32 -04:00
|
|
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>wake duration:%d us, service period:%d us", setup->min_wake_dura << 8, setup->wake_invl_mant << setup->wake_invl_expn);
|
2022-12-20 09:07:54 -05:00
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "<WIFI_EVENT_ITWT_SETUP>unexpected setup command:%d", setup->setup_cmd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void itwt_teardown_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
int32_t event_id, void *event_data)
|
|
|
|
{
|
|
|
|
wifi_event_sta_itwt_teardown_t *teardown = (wifi_event_sta_itwt_teardown_t *) event_data;
|
|
|
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_TEARDOWN>flow_id %d%s", teardown->flow_id, (teardown->flow_id == 8) ? "(all twt)" : "");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void itwt_suspend_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
int32_t event_id, void *event_data)
|
|
|
|
{
|
|
|
|
wifi_event_sta_itwt_suspend_t *suspend = (wifi_event_sta_itwt_suspend_t *) event_data;
|
|
|
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SUSPEND>status:%d, flow_id_bitmap:0x%x, actual_suspend_time_ms:[%lu %lu %lu %lu %lu %lu %lu %lu]",
|
|
|
|
suspend->status, suspend->flow_id_bitmap,
|
|
|
|
suspend->actual_suspend_time_ms[0], suspend->actual_suspend_time_ms[1], suspend->actual_suspend_time_ms[2], suspend->actual_suspend_time_ms[3],
|
|
|
|
suspend->actual_suspend_time_ms[4], suspend->actual_suspend_time_ms[5], suspend->actual_suspend_time_ms[6], suspend->actual_suspend_time_ms[7]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void itwt_probe_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
int32_t event_id, void *event_data)
|
|
|
|
{
|
|
|
|
wifi_event_sta_itwt_probe_t *probe = (wifi_event_sta_itwt_probe_t *) event_data;
|
|
|
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_PROBE>status:%s, reason:0x%x", itwt_probe_status_to_str(probe->status), probe->reason);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void wifi_itwt(void)
|
|
|
|
{
|
|
|
|
ESP_ERROR_CHECK(esp_netif_init());
|
|
|
|
wifi_event_group = xEventGroupCreate();
|
|
|
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
|
|
netif_sta = esp_netif_create_default_wifi_sta();
|
|
|
|
assert(netif_sta);
|
|
|
|
|
|
|
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
|
|
|
WIFI_EVENT_STA_START,
|
|
|
|
&connect_handler,
|
|
|
|
NULL,
|
|
|
|
NULL));
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
|
|
|
WIFI_EVENT_STA_DISCONNECTED,
|
|
|
|
&disconnect_handler,
|
|
|
|
NULL,
|
|
|
|
NULL));
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
|
|
|
|
IP_EVENT_STA_GOT_IP,
|
|
|
|
&got_ip_handler,
|
|
|
|
NULL,
|
|
|
|
NULL));
|
|
|
|
/* itwt */
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
|
|
|
WIFI_EVENT_ITWT_SETUP,
|
|
|
|
&itwt_setup_handler,
|
|
|
|
NULL,
|
|
|
|
NULL));
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
|
|
|
WIFI_EVENT_ITWT_TEARDOWN,
|
|
|
|
&itwt_teardown_handler,
|
|
|
|
NULL,
|
|
|
|
NULL));
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
|
|
|
WIFI_EVENT_ITWT_SUSPEND,
|
|
|
|
&itwt_suspend_handler,
|
|
|
|
NULL,
|
|
|
|
NULL));
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
|
|
|
WIFI_EVENT_ITWT_PROBE,
|
|
|
|
&itwt_probe_handler,
|
|
|
|
NULL,
|
|
|
|
NULL));
|
|
|
|
|
|
|
|
wifi_config_t wifi_config = {
|
|
|
|
.sta = {
|
|
|
|
.ssid = DEFAULT_SSID,
|
|
|
|
.password = DEFAULT_PWD,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
|
|
|
|
|
|
|
esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT20);
|
|
|
|
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_11AX);
|
|
|
|
esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
|
|
|
|
|
2023-04-05 22:46:32 -04:00
|
|
|
#if CONFIG_EXAMPLE_ENABLE_STATIC_IP
|
|
|
|
example_set_static_ip(netif_sta);
|
|
|
|
#endif
|
|
|
|
|
2022-12-20 09:07:54 -05:00
|
|
|
ESP_ERROR_CHECK(esp_wifi_start());
|
|
|
|
|
2022-12-28 23:58:02 -05:00
|
|
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
|
|
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
2022-12-20 09:07:54 -05:00
|
|
|
esp_wifi_enable_rx_statistics(true, true);
|
|
|
|
#else
|
|
|
|
esp_wifi_enable_rx_statistics(true, false);
|
|
|
|
#endif
|
|
|
|
#endif
|
2022-12-28 23:58:02 -05:00
|
|
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
2022-12-20 09:07:54 -05:00
|
|
|
esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_VO, true); //VO, mgmt
|
|
|
|
esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); //BE, data
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void app_main(void)
|
|
|
|
{
|
|
|
|
// Initialize NVS
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-02-05 04:18:49 -05:00
|
|
|
#if CONFIG_PM_ENABLE
|
2022-12-20 09:07:54 -05:00
|
|
|
// Configure dynamic frequency scaling:
|
|
|
|
// maximum and minimum frequencies are set in sdkconfig,
|
|
|
|
// automatic light sleep is enabled if tickless idle support is enabled.
|
2023-02-22 01:03:39 -05:00
|
|
|
esp_pm_config_t pm_config = {
|
2022-12-20 09:07:54 -05:00
|
|
|
.max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,
|
|
|
|
.min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
|
|
|
|
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
|
|
|
.light_sleep_enable = true
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
ESP_ERROR_CHECK( esp_pm_configure(&pm_config) );
|
|
|
|
ESP_ERROR_CHECK( ret );
|
|
|
|
|
|
|
|
#else
|
|
|
|
printf("\n =================================================\n");
|
|
|
|
printf(" | Test WiFi 6 itwt |\n");
|
|
|
|
printf(" =================================================\n\n");
|
|
|
|
|
|
|
|
esp_console_repl_t *repl = NULL;
|
|
|
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
|
|
|
repl_config.prompt = "itwt>";
|
|
|
|
|
|
|
|
// init console REPL environment
|
|
|
|
#if CONFIG_ESP_CONSOLE_UART
|
|
|
|
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
|
|
|
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
|
|
|
|
#elif CONFIG_ESP_CONSOLE_USB_CDC
|
|
|
|
esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();
|
|
|
|
ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &repl));
|
|
|
|
#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
|
|
|
esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
|
|
|
|
ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// start console REPL
|
|
|
|
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//start wifi
|
|
|
|
wifi_itwt();
|
|
|
|
// register commands
|
|
|
|
register_system();
|
|
|
|
register_wifi_itwt();
|
|
|
|
register_wifi_stats();
|
|
|
|
|
|
|
|
}
|