esp_wifi: itwt support light sleep

This commit is contained in:
Xu Xiao 2023-04-06 10:46:32 +08:00
parent 6e67c54a92
commit 2f20406202
8 changed files with 137 additions and 24 deletions

View File

@ -71,7 +71,7 @@ pm_is_waked = 0x40000c9c;
//pm_keep_alive = 0x40000ca0;
/* pm_on_beacon_rx = 0x40000ca4; */
pm_on_data_rx = 0x40000ca8;
pm_on_tbtt = 0x40000cac;
//pm_on_tbtt = 0x40000cac;
pm_parse_beacon = 0x40000cb0;
//pm_process_tim = 0x40000cb4;
//pm_rx_beacon_process = 0x40000cb8;

@ -1 +1 @@
Subproject commit e61fec6b57f6a16ae6747ce3b52d7fc6286425bb
Subproject commit 515b89441b26f0c76daedb10ac0f411a4c67cccb

View File

@ -124,7 +124,11 @@ static void socket_recv(int recv_socket, struct sockaddr_storage listen_addr, ui
uint8_t *buffer;
int want_recv = 0;
int actual_recv = 0;
#ifdef CONFIG_LWIP_IPV6
socklen_t socklen = (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
#else
socklen_t socklen = sizeof(struct sockaddr_in);
#endif
const char *error_log = (type == IPERF_TRANS_TYPE_TCP) ? "tcp server recv" : "udp server recv";
buffer = s_iperf_ctrl.buffer;
@ -157,7 +161,11 @@ static void socket_send(int send_socket, struct sockaddr_storage dest_addr, uint
int64_t prev_time = 0;
int64_t send_time = 0;
int err = 0;
#ifdef CONFIG_LWIP_IPV6
const socklen_t socklen = (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
#else
const socklen_t socklen = sizeof(struct sockaddr_in);
#endif
const char *error_log = (type == IPERF_TRANS_TYPE_TCP) ? "tcp client send" : "udp client send";
buffer = s_iperf_ctrl.buffer;
@ -225,11 +233,15 @@ static esp_err_t IRAM_ATTR iperf_run_tcp_server(void)
struct timeval timeout = { 0 };
socklen_t addr_len = sizeof(struct sockaddr);
struct sockaddr_storage listen_addr = { 0 };
struct sockaddr_in6 listen_addr6 = { 0 };
struct sockaddr_in listen_addr4 = { 0 };
#ifdef CONFIG_LWIP_IPV6
struct sockaddr_in6 listen_addr6 = { 0 };
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#else
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Invalid AF types");
#endif
#ifdef CONFIG_LWIP_IPV6
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
// The TCP server listen at the address "::", which means all addresses can be listened to.
inet6_aton("::", &listen_addr6.sin6_addr);
@ -250,7 +262,9 @@ static esp_err_t IRAM_ATTR iperf_run_tcp_server(void)
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Error occurred during listen: errno %d", errno);
memcpy(&listen_addr, &listen_addr6, sizeof(listen_addr6));
} else if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
} else
#endif
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
listen_addr4.sin_family = AF_INET;
listen_addr4.sin_port = htons(s_iperf_ctrl.cfg.sport);
listen_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.source_ip4;
@ -313,12 +327,15 @@ static esp_err_t iperf_run_tcp_client(void)
int err = 0;
esp_err_t ret = ESP_OK;
struct sockaddr_storage dest_addr = { 0 };
struct sockaddr_in6 dest_addr6 = { 0 };
struct sockaddr_in dest_addr4 = { 0 };
struct timeval timeout = { 0 };
#ifdef CONFIG_LWIP_IPV6
struct sockaddr_in6 dest_addr6 = { 0 };
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#else
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Invalid AF types");
#endif
#ifdef CONFIG_LWIP_IPV6
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
client_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
ESP_GOTO_ON_FALSE((client_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
@ -331,7 +348,9 @@ static esp_err_t iperf_run_tcp_client(void)
ESP_GOTO_ON_FALSE((err == 0), ESP_FAIL, exit, TAG, "Socket unable to connect: errno %d", errno);
ESP_LOGI(TAG, "Successfully connected");
memcpy(&dest_addr, &dest_addr6, sizeof(dest_addr6));
} else if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
} else
#endif
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ESP_GOTO_ON_FALSE((client_socket >= 0), ESP_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
@ -378,11 +397,14 @@ static esp_err_t IRAM_ATTR iperf_run_udp_server(void)
esp_err_t ret = ESP_OK;
struct timeval timeout = { 0 };
struct sockaddr_storage listen_addr = { 0 };
struct sockaddr_in6 listen_addr6 = { 0 };
struct sockaddr_in listen_addr4 = { 0 };
#ifdef CONFIG_LWIP_IPV6
struct sockaddr_in6 listen_addr6 = { 0 };
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#else
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#endif
#ifdef CONFIG_LWIP_IPV6
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
// The UDP server listen at the address "::", which means all addresses can be listened to.
inet6_aton("::", &listen_addr6.sin6_addr);
@ -400,7 +422,9 @@ static esp_err_t IRAM_ATTR iperf_run_udp_server(void)
ESP_LOGI(TAG, "Socket bound, port %" PRIu16, listen_addr6.sin6_port);
memcpy(&listen_addr, &listen_addr6, sizeof(listen_addr6));
} else if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
} else
#endif
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
listen_addr4.sin_family = AF_INET;
listen_addr4.sin_port = htons(s_iperf_ctrl.cfg.sport);
listen_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.source_ip4;
@ -442,11 +466,14 @@ static esp_err_t iperf_run_udp_client(void)
int opt = 1;
esp_err_t ret = ESP_OK;
struct sockaddr_storage dest_addr = { 0 };
struct sockaddr_in6 dest_addr6 = { 0 };
struct sockaddr_in dest_addr4 = { 0 };
#ifdef CONFIG_LWIP_IPV6
struct sockaddr_in6 dest_addr6 = { 0 };
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#else
ESP_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), ESP_FAIL, exit, TAG, "Ivalid AF types");
#endif
#ifdef CONFIG_LWIP_IPV6
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
inet6_aton(s_iperf_ctrl.cfg.destination_ip6, &dest_addr6.sin6_addr);
dest_addr6.sin6_family = AF_INET6;
@ -458,7 +485,9 @@ static esp_err_t iperf_run_udp_client(void)
setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
memcpy(&dest_addr, &dest_addr6, sizeof(dest_addr6));
} else if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
} else
#endif
if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
dest_addr4.sin_family = AF_INET;
dest_addr4.sin_port = htons(s_iperf_ctrl.cfg.dport);
dest_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.destination_ip4;

View File

@ -365,8 +365,15 @@ static void cmd_ping_on_ping_success(esp_ping_handle_t hdl, void *args)
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len));
esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time));
#ifdef CONFIG_LWIP_IPV6
printf("%" PRIu32 " bytes from %s icmp_seq=%d ttl=%d time=%" PRIu32 " ms\n",
recv_len, inet_ntoa(target_addr.u_addr.ip4), seqno, ttl, elapsed_time);
#else
printf("%" PRIu32 " bytes from %s icmp_seq=%d ttl=%d time=%" PRIu32 " ms\n",
recv_len, inet_ntoa(target_addr.addr), seqno, ttl, elapsed_time);
#endif
}
static void cmd_ping_on_ping_timeout(esp_ping_handle_t hdl, void *args)
@ -375,7 +382,11 @@ static void cmd_ping_on_ping_timeout(esp_ping_handle_t hdl, void *args)
ip_addr_t target_addr;
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
#ifdef CONFIG_LWIP_IPV6
printf("From %s icmp_seq=%d timeout\n", inet_ntoa(target_addr.u_addr.ip4), seqno);
#else
printf("From %s icmp_seq=%d timeout\n", inet_ntoa(target_addr.addr), seqno);
#endif
}
static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args)
@ -391,9 +402,12 @@ static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args)
uint32_t loss = (uint32_t)((1 - ((float)received) / transmitted) * 100);
if (IP_IS_V4(&target_addr)) {
printf("\n--- %s ping statistics ---\n", inet_ntoa(*ip_2_ip4(&target_addr)));
} else {
}
#ifdef CONFIG_LWIP_IPV6
else {
printf("\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&target_addr)));
}
#endif
printf("%" PRIu32 " packets transmitted, %" PRIu32 " received, %" PRIu32 "%% packet loss, time %" PRIu32 "ms\n",
transmitted, received, loss, total_time_ms);
// delete the ping sessions, so that we clean up all resources and can create a new ping session
@ -450,10 +464,13 @@ static int do_ping_cmd(int argc, char **argv)
if (res->ai_family == AF_INET) {
struct in_addr addr4 = ((struct sockaddr_in *) (res->ai_addr))->sin_addr;
inet_addr_to_ip4addr(ip_2_ip4(&target_addr), &addr4);
} else {
}
#ifdef CONFIG_LWIP_IPV6
else {
struct in6_addr addr6 = ((struct sockaddr_in6 *) (res->ai_addr))->sin6_addr;
inet6_addr_to_ip6addr(ip_2_ip6(&target_addr), &addr6);
}
#endif
freeaddrinfo(res);
config.target_addr = target_addr;

View File

@ -12,6 +12,32 @@ menu "Example Configuration"
help
WiFi password (WPA or WPA2) for the example to use.
config EXAMPLE_ENABLE_STATIC_IP
bool "enable static ip"
default y
help
Enable static IP
config EXAMPLE_STATIC_IP_ADDR
string "Static IP address"
default "192.168.4.2"
depends on EXAMPLE_ENABLE_STATIC_IP
help
Set static IP address.
config EXAMPLE_STATIC_NETMASK_ADDR
string "Static netmask address"
default "255.255.255.0"
depends on EXAMPLE_ENABLE_STATIC_IP
help
Set static netmask address.
config EXAMPLE_STATIC_GW_ADDR
string "Static gateway address"
default "192.168.4.1"
depends on EXAMPLE_ENABLE_STATIC_IP
help
Set static gateway address.
menu "iTWT Configuration"
config EXAMPLE_ITWT_TRIGGER_ENABLE
bool "trigger-enabled"

View File

@ -17,6 +17,7 @@
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.
*/
#include <netdb.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
@ -28,6 +29,7 @@
#include "wifi_cmd.h"
#include "esp_wifi_he.h"
#include "esp_pm.h"
#include "esp_timer.h"
/*******************************************************
* Constants
@ -69,6 +71,28 @@ EventGroupHandle_t wifi_event_group;
/*******************************************************
* Function Definitions
*******************************************************/
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
}
static const char *itwt_probe_status_to_str(wifi_itwt_probe_status_t status)
{
switch (status) {
@ -87,20 +111,19 @@ static void got_ip_handler(void *arg, esp_event_base_t event_base,
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
/* setup a trigger-based announce individual TWT agreement. */
esp_err_t err = ESP_OK;
int flow_id = 0;
wifi_phy_mode_t phymode;
wifi_config_t sta_cfg = { 0, };
esp_wifi_get_config(WIFI_IF_STA, &sta_cfg);
esp_wifi_sta_get_negotiated_phymode(&phymode);
if (phymode == WIFI_PHY_MODE_HE20) {
esp_err_t err = ESP_OK;
int flow_id = 0;
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");
}
@ -130,7 +153,7 @@ static void itwt_setup_handler(void *arg, esp_event_base_t event_base,
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);
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>wake duration:%d us, service period:%d ms", setup->min_wake_dura << 8, setup->wake_invl_mant << setup->wake_invl_expn);
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);
} else {
ESP_LOGE(TAG, "<WIFI_EVENT_ITWT_SETUP>unexpected setup command:%d", setup->setup_cmd);
}
@ -221,6 +244,10 @@ static void wifi_itwt(void)
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);
#if CONFIG_EXAMPLE_ENABLE_STATIC_IP
example_set_static_ip(netif_sta);
#endif
ESP_ERROR_CHECK(esp_wifi_start());
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS

View File

@ -16,5 +16,6 @@ CONFIG_ESP_WIFI_SLP_IRAM_OPT=y
CONFIG_ESP_GRATUITOUS_ARP=n
CONFIG_LWIP_ESP_GRATUITOUS_ARP=n
CONFIG_FREERTOS_HZ=1000
# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set
# CONFIG_ESP_GRATUITOUS_ARP is not set

View File

@ -18,3 +18,16 @@ CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64
CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS=n
CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS=n
CONFIG_LWIP_IPV6=n
CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=10
CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
CONFIG_ESP_PHY_MAC_BB_PD=y
#CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP=y
CONFIG_MBEDTLS_HARDWARE_AES=n
CONFIG_MBEDTLS_HARDWARE_MPI=n
CONFIG_MBEDTLS_HARDWARE_SHA=n
CONFIG_MBEDTLS_HARDWARE_ECC=n