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
2023-06-05 08:06:52 -04:00
# define ITWT_SETUP_SUCCESS 1
2022-12-20 09:07:54 -05:00
# if CONFIG_EXAMPLE_ITWT_TRIGGER_ENABLE
2023-05-26 03:11:47 -04:00
uint8_t trigger_enabled = 1 ;
2022-12-20 09:07:54 -05:00
# else
2023-05-26 03:11:47 -04:00
uint8_t trigger_enabled = 0 ;
2022-12-20 09:07:54 -05:00
# endif
# if CONFIG_EXAMPLE_ITWT_ANNOUNCED
2023-05-26 03:11:47 -04:00
uint8_t flow_type_announced = 1 ;
2022-12-20 09:07:54 -05:00
# else
2023-05-26 03:11:47 -04:00
uint8_t flow_type_announced = 0 ;
2022-12-20 09:07:54 -05:00
# 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 ;
2023-05-26 03:11:47 -04:00
wifi_twt_setup_config_t setup_config = {
. setup_cmd = TWT_REQUEST ,
. flow_id = 0 ,
. twt_id = CONFIG_EXAMPLE_ITWT_ID ,
. flow_type = flow_type_announced ? 0 : 1 ,
. min_wake_dura = CONFIG_EXAMPLE_ITWT_MIN_WAKE_DURA ,
2023-06-05 08:06:52 -04:00
. wake_duration_unit = CONFIG_EXAMPLE_ITWT_WAKE_DURATION_UNIT ,
2023-05-26 03:11:47 -04:00
. wake_invl_expn = CONFIG_EXAMPLE_ITWT_WAKE_INVL_EXPN ,
. wake_invl_mant = CONFIG_EXAMPLE_ITWT_WAKE_INVL_MANT ,
. trigger = trigger_enabled ,
. timeout_time_ms = CONFIG_EXAMPLE_ITWT_SETUP_TIMEOUT_TIME_MS ,
} ;
err = esp_wifi_sta_itwt_setup ( & setup_config ) ;
2022-12-20 09:07:54 -05:00
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 " ) ;
}
}
2023-05-31 10:32:55 -04:00
static void start_handler ( void * arg , esp_event_base_t event_base ,
2022-12-20 09:07:54 -05:00
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 ;
2023-06-05 08:06:52 -04:00
if ( setup - > status = = ITWT_SETUP_SUCCESS ) {
2022-12-20 09:07:54 -05:00
/* TWT Wake Interval = TWT Wake Interval Mantissa * (2 ^ TWT Wake Interval Exponent) */
2023-06-05 08:06:52 -04:00
ESP_LOGI ( TAG , " <WIFI_EVENT_ITWT_SETUP>twt_id:%d, flow_id:%d, %s, %s, wake_dura:%d, wake_dura_unit:%d, wake_invl_e:%d, wake_invl_m:%d " , setup - > config . twt_id ,
2023-05-26 03:11:47 -04:00
setup - > config . flow_id , setup - > config . trigger ? " trigger-enabled " : " non-trigger-enabled " , setup - > config . flow_type ? " unannounced " : " announced " ,
2023-06-05 08:06:52 -04:00
setup - > config . min_wake_dura , setup - > config . wake_duration_unit , setup - > config . wake_invl_expn , setup - > config . wake_invl_mant ) ;
ESP_LOGI ( TAG , " <WIFI_EVENT_ITWT_SETUP>target wake time:%lld, wake duration:%d us, service period:%d us " , setup - > target_wake_time , setup - > config . min_wake_dura < < ( setup - > config . wake_duration_unit = = 1 ? 10 : 8 ) ,
setup - > config . wake_invl_mant < < setup - > config . wake_invl_expn ) ;
2022-12-20 09:07:54 -05:00
} else {
2023-06-05 08:06:52 -04:00
if ( setup - > status = = ESP_ERR_WIFI_TWT_SETUP_TIMEOUT ) {
ESP_LOGE ( TAG , " <WIFI_EVENT_ITWT_SETUP>twt_id:%d, timeout of receiving twt setup response frame " , setup - > config . twt_id ) ;
} else if ( setup - > status = = ESP_ERR_WIFI_TWT_SETUP_TXFAIL ) {
ESP_LOGE ( TAG , " <WIFI_EVENT_ITWT_SETUP>twt_id:%d, twt setup frame tx failed, reason: %d " , setup - > config . twt_id , setup - > reason ) ;
} else if ( setup - > status = = ESP_ERR_WIFI_TWT_SETUP_REJECT ) {
ESP_LOGE ( TAG , " <WIFI_EVENT_ITWT_SETUP>twt_id:%d, twt setup request was rejected, setup cmd: %d " , setup - > config . twt_id , setup - > config . setup_cmd ) ;
} else {
ESP_LOGE ( TAG , " <WIFI_EVENT_ITWT_SETUP>twt_id:%d, twt setup failed, status: %d " , setup - > config . twt_id , setup - > status ) ;
}
2022-12-20 09:07:54 -05:00
}
}
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 ,
2023-05-31 10:32:55 -04:00
& start_handler ,
2022-12-20 09:07:54 -05:00
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 ( ) ;
}