From 2e5ea3a51bd1a87840cbaa0d368f774e08de61c6 Mon Sep 17 00:00:00 2001 From: liu zhifu Date: Tue, 28 Apr 2020 15:57:18 +0800 Subject: [PATCH] Optimize debug log 1. optimize wifi debug log 2. optimize lwip debug log --- components/esp32/include/wifi_debug.h | 466 ++++++++ components/esp32/lib | 2 +- components/esp32/wifi_debug.c | 366 ++++++ components/esp32/wifi_init.c | 2 + components/esp_debug/CMakeLists.txt | 13 + components/esp_debug/Kconfig | 228 ++++ components/esp_debug/Makefile.projbuild | 0 components/esp_debug/component.mk | 5 + components/esp_debug/include/esp_debug.h | 100 ++ components/esp_debug/src/esp_debug.c | 359 ++++++ components/lwip/lwip | 2 +- components/lwip/port/esp32/debug/lwip_debug.c | 1030 ++++++++++++++--- .../lwip/port/esp32/freertos/sys_arch.c | 4 + .../port/esp32/include/debug/lwip_debug.h | 25 +- 14 files changed, 2413 insertions(+), 189 deletions(-) create mode 100644 components/esp32/include/wifi_debug.h create mode 100644 components/esp32/wifi_debug.c create mode 100644 components/esp_debug/CMakeLists.txt create mode 100644 components/esp_debug/Kconfig create mode 100644 components/esp_debug/Makefile.projbuild create mode 100644 components/esp_debug/component.mk create mode 100644 components/esp_debug/include/esp_debug.h create mode 100644 components/esp_debug/src/esp_debug.c diff --git a/components/esp32/include/wifi_debug.h b/components/esp32/include/wifi_debug.h new file mode 100644 index 0000000000..0497398a50 --- /dev/null +++ b/components/esp32/include/wifi_debug.h @@ -0,0 +1,466 @@ +// Copyright 2020-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + * All the APIs declared here are internal only APIs, it can only be used by + * espressif internal modules, such as SSC, LWIP, TCPIP adapter etc, espressif + * customers are not recommended to use them. + * + * If someone really want to use specified APIs declared in here, please contact + * espressif AE/developer to make sure you know the limitations or risk of + * the API, otherwise you may get unexpected behavior!!! + * + */ + + +#ifndef __ESP_WIFI_DEBUG_H__ +#define __ESP_WIFI_DEBUG_H__ + +typedef struct { + uint32_t diag0; + uint32_t diag1; + uint32_t diag2; + uint32_t diag3; + uint32_t diag4; + uint32_t diag5; + uint32_t diag6; + uint32_t diag7; + uint32_t diag8; + uint32_t diag9; + uint32_t diag10; + uint32_t diag12; + uint32_t diag_sel; +} wifi_stats_reg_diag_t; + +typedef struct { + uint32_t rx_data_suc; + uint32_t rx_end; + uint32_t rx_full; + uint32_t rx_full1; + uint32_t rx_bufbk; + uint32_t rx_cck_err; + uint32_t rx_ofdm_err; + uint32_t rx_agc_err; + uint32_t rx_sf; + uint32_t rx_abort; + uint32_t rx_fcs_err; + uint32_t rx_fifo_overflow; + uint32_t rx_apentrybuf_ful; + uint32_t rx_other_uc; + uint32_t rx_tkip_err; + uint32_t rx_samebm_err; + uint32_t rx_ack_int; + uint32_t rx_rts_int; + uint32_t rx_cts_int; + uint32_t rx_rifs_int; + uint32_t rx_block_err; + uint32_t rx_freqhop_err; + uint32_t txrts_int; + uint32_t txcts_int; + uint32_t txrxack_int; + uint32_t txrxcts_int; + uint32_t rxtrigger; + uint32_t rxtxhung; + uint32_t rxtxpanic; +} wifi_stats_reg_cnt_t; + +typedef struct { +} wifi_stats_reg_filter_t; + +typedef struct { +} wifi_stats_reg_crypto_t; + +typedef struct { +} wifi_stats_reg_ba_t; + +typedef struct { + uint32_t bbst; + uint32_t bbwd; + uint32_t frd; + uint32_t frd0; + uint32_t frd1; + uint32_t frd2; + uint32_t frd3; + uint32_t frd4; + uint32_t int_st; +} wifi_stats_reg_misc_t; + +typedef struct { + uint32_t max; + uint32_t alloc; + uint32_t avail; + uint32_t total_free; + uint32_t total_alloc; + uint32_t total_fail; +} wifi_stats_one_buf_t; + +#define WIFI_STATS_BUF_MAX 9 +typedef struct { + wifi_stats_one_buf_t buf[WIFI_STATS_BUF_MAX]; +} wifi_stats_buf_t; + +typedef struct { + wifi_stats_reg_diag_t diag; + wifi_stats_reg_misc_t misc; + wifi_stats_reg_cnt_t cnt; +} wifi_stats_reg_t; + +typedef struct { + uint32_t rx_suc; + uint32_t rx_hung; + uint32_t tx_complete; + uint32_t tx_enable; + uint32_t tx_collision; + uint32_t panic_reset; + uint32_t bb_wdt; + uint32_t tbtt; + + uint32_t pp_post_fail; + + uint32_t rx_sniffer_pingpong_full; + uint32_t rx_sniffer_null; + uint32_t rx_sniffer_reset_retry; + uint32_t rx_sniffer_reset_succ; + uint32_t rx_sniffer_reset; + uint32_t rx_sniffer_oversize; + uint32_t rx_sniffer_mimo; + uint32_t rx_sniffer_non_mimo; + + uint32_t bb_wdt_bt; + uint32_t bb_wdt_wifi_rst; + uint32_t bb_wdt_wifi_not_rst; +} wifi_stats_int_t; + +typedef struct { + wifi_stats_reg_t reg; + wifi_stats_buf_t buf; + wifi_stats_int_t interrupt; +} wifi_stats_mandatory_t; + +#define WIFI_LMAC_AC_NUM 6 +#define WIFI_LMAC_QUEUE_NUM 16 + +typedef struct { + uint32_t tx_data_all; + uint32_t tx_arp; + uint32_t tx_raw; + uint32_t tx_dhcp; + uint32_t tx_ps_q; + uint32_t tx_drop_data_arg; + uint32_t tx_drop_data_if; + uint32_t tx_drop_data_all; + uint32_t tx_drop_data_conn_null; + uint32_t tx_drop_data_not_run; + uint32_t tx_drop_data_not_assoc; + uint32_t tx_drop_data_not_auth; + uint32_t tx_drop_data_no_mem; + uint32_t tx_drop_data_qfull; + uint32_t tx_drop_data_post_fail; + uint32_t tx_drop_data_buf; + uint32_t tx_drop_data_ps; + uint32_t tx_task_yield; + uint32_t tx_buffer_not_home_chan; + uint32_t tx_buffer_not_home_chan_free; + uint32_t tx_buffer_not_home_chan_scan; +} wifi_stats_hmac_tx_t; + +typedef struct { + uint32_t r1_all; + uint32_t r1_ampdu; + uint32_t r1_mutiple_blocks; + uint32_t r1_data_mpdu; + uint32_t r1_mgmt; + uint32_t r1_mgmt_probe_req; + uint32_t r1_mgmt_beacon; + uint32_t r1_ctrl_bar; + uint32_t r1_ctrl_ba; + uint32_t r1_ctrl_pspoll; + uint32_t r1_ctrl_others; + uint32_t r1_sniffer_mimo; + uint32_t r1_drop; + uint32_t r1_drop_if_mismatch; + uint32_t r1_drop_sniffer_state; + uint32_t r1_drop_type_err; + uint32_t r1_drop_mpdu_multiple_blocks; + + uint32_t r2_drop_multiple_blocks; + uint32_t r2_drop_mpdu_no_mem; + + uint32_t r3_drop_ampdu_too_long; + uint32_t r3_drop_ampdu_too_short; + uint32_t r3_drop_ampdu_state; + uint32_t r3_drop_ampdu_no_mem; + uint32_t r3_drop_ampdu_len; + uint32_t r3_drop_ampdu_ds; + + uint32_t r4_drop_ampdu_proc; + uint32_t r4_drop_mpdu_proc; + uint32_t r4_drop_frag; + uint32_t r4_drop_state; + uint32_t r4_drop_tkipmic; + uint32_t r4_drop_sta_if; + uint32_t r4_drop_ap_if; + uint32_t r4_drop_if_mismatch; + + uint32_t r5_sniffer_ampdu; + uint32_t r5_drop_sniffer_filter; + uint32_t r5_drop_sniffer_no_mem; + uint32_t r5_drop_sniffer_q_fail; + + uint32_t r6_sniffer_mimo; + uint32_t r6_sniffer_single_block; + uint32_t r6_sniffer_multiple_blocks; + uint32_t r6_drop_sniffer_filter; + uint32_t r6_drop_sniffer_no_mem; + uint32_t r6_drop_sniffer_q_fail; + + uint32_t r7_sniffer_mimo; + uint32_t r7_drop_sniffer_no_mem; + uint32_t r7_drop_sniffer_post; + uint32_t r7_drop_sniffer_others; + + uint32_t r8_reset_rx_base; + uint32_t r8_reload; + + uint32_t rh1_sta_drop_conn_null; + uint32_t rh1_sta_drop_too_short; + uint32_t rh1_sta_drop_wrong_version; + uint32_t rh1_sta_drop_not_my_bss; + uint32_t rh1_sta_drop_mgmt_too_short1; + uint32_t rh1_sta_drop_mgmt_probe_inq; + uint32_t rh1_sta_drop_dup; + uint32_t rh1_sta_drop_data_not_assoc; + uint32_t rh1_sta_drop_data_too_short; + uint32_t rh1_sta_drop_data_not_fromds; + uint32_t rh1_sta_drop_data_invalid_key; + uint32_t rh1_sta_drop_data_frag; + uint32_t rh1_sta_drop_data_mic; + uint32_t rh1_sta_drop_data_encap; + uint32_t rh1_sta_drop_data_null_key; + uint32_t rh1_sta_drop_data_unencrypt; + uint32_t rh1_sta_data_to_lwip; + uint32_t rh1_sta_mgmt; + uint32_t rh1_sta_drop_mgmt_not_nods; + uint32_t rh1_sta_drop_mgmt_too_short2; + uint32_t rh1_sta_drop_mgmt_bip_check; + uint32_t rh1_sta_ctrl; + + uint32_t rh2_sta_eapol_wps_succ; + uint32_t rh2_sta_eapol_wps_fail; + uint32_t rh2_sta_eapol_wps_null_handle; + uint32_t rh2_sta_drop_not_8021x_auth; + uint32_t rh2_sta_drop_not_allow_eapol; + uint32_t rh2_sta_eapol_wpa2e_succ; + uint32_t rh2_sta_drop_eapol_wpa2e_null_handle; + uint32_t rh2_sta_drop_eapol_wpa2e_state; + uint32_t rh2_sta_eapol_wpa_succ; + uint32_t rh2_sta_drop_eapol_wpa_fail; + uint32_t rh2_sta_drop_eapol_wpa_null_handle; + + uint32_t rh3_data_amsdu; + uint32_t rh3_drop_data_amsdu_too_short; + uint32_t rh3_drop_data_amsdu_no_mem; + uint32_t rh3_drop_data_amsdu_remain_too_short; + uint32_t rh3_sta_data_amsdu_mpdu; + uint32_t rh3_ap_data_amsdu_mpdu; + + uint32_t rh4_sta_mgmt_beacon; + uint32_t rh4_sta_mgmt_probe_resp; + uint32_t rh4_sta_mgmt_auth; + uint32_t rh4_sta_mgmt_deauth; + uint32_t rh4_sta_mgmt_assoc; + uint32_t rh4_sta_mgmt_action; + uint32_t rh4_sta_drop_mgmt_disassoc_unencrypt; + uint32_t rh4_sta_drop_mgmt_disassoc_not_my; + uint32_t rh4_sta_drop_mgmt_unencrypt; + uint32_t rh4_sta_mgmt_disassoc; + uint32_t rh4_sta_drop_mgmt_unexpected; + + uint32_t rh5_sta_beacon_csa; + uint32_t rh5_sta_drop_beacon_out_of_reg; + + uint32_t rh1_ap_data_fwd; + uint32_t rh1_ap_drop_data_null_cb; + uint32_t rh1_ap_data_to_lwip; + uint32_t rh1_ap_drop_data_rxcb_null; + uint32_t rh1_ap_drop_wrong_version; + uint32_t rh1_ap_drop_ds2ds; + uint32_t rh1_ap_drop_data_null_bss; + uint32_t rh1_ap_drop_nondata_null_bss; + uint32_t rh1_ap_drop_null_bss; + uint32_t rh1_ap_drop_bcast_null_bss; + uint32_t rh1_ap_drop_not_my_bss1; + uint32_t rh1_ap_drop_not_my_bss2; + uint32_t rh1_ap_drop_too_short1; + uint32_t rh1_ap_drop_too_short2; + uint32_t rh1_ap_drop_mgmt_too_short1; + uint32_t rh1_ap_drop_mgmt_too_short2; + uint32_t rh1_ap_drop_data_too_short; + uint32_t rh1_ap_drop_data_not_tods; + uint32_t rh1_ap_drop_data_not_assoc; + uint32_t rh1_ap_drop_data_wep; + uint32_t rh1_ap_drop_data_key; + uint32_t rh1_ap_drop_data_decap; + uint32_t rh1_ap_drop_data_8021x_auth; + uint32_t rh1_ap_eapol_succ1; + uint32_t rh1_ap_eapol_succ2; + uint32_t rh1_ap_drop_eapol_null_handle1; + uint32_t rh1_ap_drop_eapol_null_handle2; + uint32_t rh1_ap_drop_data_unencrypt; + uint32_t rh1_ap_mgmt; + uint32_t rh1_ap_drop_mgmt_nods; + uint32_t rh1_ap_drop_mgmt_mcast; + uint32_t rh1_ap_drop_mgmt_encrypted; + uint32_t rh1_ap_drop_mgmt_privacy; + uint32_t rh1_ap_drop_mgmt_key; + uint32_t rh1_ap_ctrl; + uint32_t rh1_ap_drop_unknow_type; + uint32_t rh1_ap_drop_dup; + + uint32_t rh2_ap_mgmt_beacon; + uint32_t rh2_ap_mgmt_probe_resp; + uint32_t rh2_ap_mgmt_probe_req; + uint32_t rh2_ap_mgmt_auth; + uint32_t rh2_ap_mgmt_assoc; + uint32_t rh2_ap_mgmt_deauth_deassoc; + uint32_t rh2_ap_mgmt_action; + uint32_t rh2_ap_mgmt_other; + + uint32_t rh5_drop_ampdu_oos1; + uint32_t rh5_drop_ampdu_oos2; + uint32_t rh5_drop_ampdu_tid; + uint32_t rh5_drop_ampdu_frag; + uint32_t rh5_drop_ampdu_dup; + + uint32_t pm_bcn_interval; + uint32_t pm_dtim_period; + uint32_t pm_listen_interval; + uint32_t pm_tbtt; + uint32_t pm_rx_bcn; + uint32_t pm_active_timeout; + uint32_t pm_wake_tx; + uint32_t pm_wake_tbtt; + uint32_t pm_wake_tim; + uint32_t pm_wake_dtim; + uint32_t pm_sleep_null; + uint32_t pm_wake_null; + uint32_t pm_sleep; + uint32_t pm_wake; + uint32_t pm_bcn_delay_time; + uint32_t pm_max_bcn_delay_time; + uint32_t pm_avg_bcn_delay_time; + uint64_t pm_sleep_time; + uint64_t pm_wake_time; + uint64_t pm_total_time; + + uint32_t t1_en_waitq; + uint32_t t1_drop_sec; + uint32_t t1_drop_enq_fail; + uint32_t t1_drop_stop; + + uint32_t t2_ampdu_to_mpdu; + uint32_t t3_en_waitq; + + uint16_t t4_doneq_len; + uint16_t t4_waitq0_len; + uint16_t t4_waitq1_len; + uint16_t t4_rxq_len; + uint16_t t4_qlen[WIFI_LMAC_QUEUE_NUM]; + uint32_t t5_drop_aged[WIFI_LMAC_AC_NUM]; + uint16_t t6_succ[WIFI_LMAC_AC_NUM]; + uint32_t t7_drop_src[WIFI_LMAC_AC_NUM]; + uint32_t t7_drop_lrc[WIFI_LMAC_AC_NUM]; + uint32_t t7_drop_others[WIFI_LMAC_AC_NUM]; + uint32_t t8_drop_src[WIFI_LMAC_AC_NUM]; + uint32_t t8_drop_lrc[WIFI_LMAC_AC_NUM]; + uint32_t t8_drop_others[WIFI_LMAC_AC_NUM]; + uint32_t t9_drop_src[WIFI_LMAC_AC_NUM]; + uint32_t t9_drop_lrc[WIFI_LMAC_AC_NUM]; + uint32_t t9_drop_others[WIFI_LMAC_AC_NUM]; + uint32_t t10_complete_invalid_state; + uint32_t t10_complete_succ[WIFI_LMAC_AC_NUM]; + uint32_t t10_complete_cts_err[WIFI_LMAC_AC_NUM]; + uint32_t t10_complete_ack_err[WIFI_LMAC_AC_NUM]; + uint32_t t10_complete_data_err[WIFI_LMAC_AC_NUM]; + uint32_t t10_complete_other_err[WIFI_LMAC_AC_NUM]; + uint32_t t11_timeout[WIFI_LMAC_AC_NUM]; + uint32_t t12_collision[WIFI_LMAC_AC_NUM]; + uint32_t t13_complete_rts_collision_err[WIFI_LMAC_AC_NUM]; + uint32_t t13_complete_rts_seckid_err[WIFI_LMAC_AC_NUM]; + uint32_t t14_complete_data_collision_err[WIFI_LMAC_AC_NUM]; + uint32_t t14_complete_data_seckid_err[WIFI_LMAC_AC_NUM]; + uint32_t t14_complete_data_zero_err[WIFI_LMAC_AC_NUM]; + uint32_t t14_complete_data_other_err[WIFI_LMAC_AC_NUM]; + uint32_t t15_send_bar[WIFI_LMAC_AC_NUM]; + uint32_t t16_txq_free_len; + uint32_t t16_txq_forward_len; + uint32_t t16_txq_wait_len; + + wifi_stats_hmac_tx_t tx[2]; + + uint32_t pp_post_overflow; + uint32_t pp_post_fail; + + uint32_t ap_alloc; + uint32_t ap_free; + uint32_t sta_alloc; + uint32_t sta_free; + uint32_t bss_alloc; + uint32_t bss_free; + uint32_t tap_alloc; + uint32_t tap_free; + uint32_t rap_alloc; + uint32_t rap_free; + uint32_t rap_eb_alloc; + uint32_t rap_eb_free; + uint32_t scan_bss_alloc; + uint32_t scan_bss_free; +} wifi_stats_optional_t; + +typedef struct { + wifi_stats_mandatory_t mandatory; + wifi_stats_optional_t optional; +} wifi_stats_t; + +//WiFi Internal Statistics +#define WIFI_MODULE_HW_DIAG (1) +#define WIFI_MODULE_HW_COUNTERS (1<<1) +#define WIFI_MODULE_HW_MISC (1<<2) +#define WIFI_MODULE_INT_COUNTERS (1<<3) +#define WIFI_MODULE_BUFFER_COUNTERS (1<<4) +#define WIFI_MODULE_RX_COUNTERS (1<<5) +#define WIFI_MODULE_TX_COUNTERS (1<<6) +#define WIFI_MODULE_SLEEP (1<<7) +#define WIFI_MODULE_EVENT_COUNTERS (1<<8) +#define WIFI_MODULE_NVS (1<<9) +#define WIFI_MODULE_STA (1<<10) +#define WIFI_MODULE_AP (1<<11) +#define WIFI_MODULE_TRC (1<<12) + +esp_err_t esp_wifi_stats_get(wifi_stats_t *stats); +void esp_wifi_dump_stats(const wifi_stats_t *stats, uint64_t modules); +void esp_wifi_dump_info(uint64_t modules); +esp_err_t esp_wifi_stats_init(void); +esp_err_t esp_wifi_stats_deinit(void); +void esp_wifi_dump(uint64_t modules); + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_WIFI_DEBUG_H__ */ diff --git a/components/esp32/lib b/components/esp32/lib index 45c8df5abd..eee4eae632 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 45c8df5abd7ebe8f936488442c57eb8bd0055de9 +Subproject commit eee4eae63249a3701eb9d9e5a6843039212bc981 diff --git a/components/esp32/wifi_debug.c b/components/esp32/wifi_debug.c new file mode 100644 index 0000000000..d3513c0b5d --- /dev/null +++ b/components/esp32/wifi_debug.c @@ -0,0 +1,366 @@ +// Copyright 2020-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include "esp_log.h" +#include "esp_wifi_internal.h" +#include "wifi_debug.h" +#include "esp_wifi_os_adapter.h" + +#define TAG "wifid" + +static void wifi_debug_dump_diag(const wifi_stats_reg_diag_t *diag) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========>hardware diag"); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "diag0", "diag1", "diag2", "diag3", "diag4", "diag5", "diag6", "diag7", "diag8", "diag9", "diag10", "diag12", "sel"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + diag->diag0, diag->diag1, diag->diag2, diag->diag3, diag->diag4, diag->diag5, diag->diag6, diag->diag7, diag->diag8, + diag->diag9, diag->diag10, diag->diag12, diag->diag_sel); +} + +static void wifi_debug_dump_cnt(const wifi_stats_reg_cnt_t *cnt) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========>hardware counter"); + + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "rx_succ", "rx_end", "rx_full", "rx_full1", "rx_bufbk", "cck_err", "ofdm_err", "agc_err", + "rx_sf", "rx_abort", "fcs_err", "fifo_of", "apbufful", "other_uc", "tkip_err"); + + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + cnt->rx_data_suc, cnt->rx_end, cnt->rx_full, cnt->rx_full1, cnt->rx_bufbk, cnt->rx_cck_err, cnt->rx_ofdm_err, cnt->rx_agc_err, cnt->rx_sf, cnt->rx_abort, + cnt->rx_fcs_err, cnt->rx_fifo_overflow, cnt->rx_apentrybuf_ful, cnt->rx_other_uc, cnt->rx_tkip_err); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "same_err", "ack_int", "rts_int", "cts_int", "rifs_int", "blok_err", "fh_err", + "trts_int", "tcts_int", "track_in", "trcts_in", "trigger", "hung", "panic"); + + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + cnt->rx_samebm_err, cnt->rx_ack_int, cnt->rx_rts_int, cnt->rx_cts_int, cnt->rx_rifs_int, cnt->rx_block_err, cnt->rx_freqhop_err, + cnt->txrts_int, cnt->txcts_int, cnt->txrxack_int, cnt->txrxcts_int, cnt->rxtrigger, cnt->rxtxhung, cnt->rxtxpanic); +} + +static void wifi_debug_dump_misc(const wifi_stats_reg_misc_t *misc) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========>hardware misc"); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s", + "bbst", "bbwd", "frd", "frd0", "frd1", "frd2", "frd3", "frd4", "int_st"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x", + misc->bbst, misc->bbwd, misc->frd, misc->frd0, misc->frd1, misc->frd2, misc->frd3, misc->frd4, misc->int_st); +} + +static void wifi_debug_dump_int(const wifi_stats_int_t *interrupt) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========>interrupt counter"); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s", "rx_suc", "rx_hung", "tx_com", "tx_ena", "tx_col", "panic", "bb_wdt", "tbtt", "post"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x", + interrupt->rx_suc, interrupt->rx_hung, interrupt->tx_complete, interrupt->tx_enable, + interrupt->tx_collision, interrupt->panic_reset, interrupt->bb_wdt, interrupt->tbtt, interrupt->pp_post_fail); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "sni_full", "sni_null", "sni_rtry", "sni_succ", "sni_ovsz", "sni_mimo", "sni_nomi", "bb_wdt", "bb_brst", "bb_wrst", "bb_nwrst"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + interrupt->rx_sniffer_pingpong_full, interrupt->rx_sniffer_null, interrupt->rx_sniffer_reset_retry, interrupt->rx_sniffer_reset_succ, interrupt->rx_sniffer_oversize, + interrupt->rx_sniffer_mimo, interrupt->rx_sniffer_non_mimo, interrupt->bb_wdt, interrupt->bb_wdt_bt, interrupt->bb_wdt_wifi_rst, interrupt->bb_wdt_wifi_not_rst); +} + +static void wifi_debug_dump_buf(const wifi_stats_t *stats) +{ + const wifi_stats_buf_t *buf = &stats->mandatory.buf; + const wifi_stats_optional_t *mem = &stats->optional; + int i=0; + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========>buf counter"); + ESP_LOGI(TAG, "%1s %3s %5s %5s %8s %8s %8s", "t", "max", "alloc", "avail", "t_free", "t_alloc", "t_fail"); + + for (i=0; ibuf[i].max, buf->buf[i].alloc, buf->buf[i].avail, + buf->buf[i].total_free, buf->buf[i].total_alloc, buf->buf[i].total_fail); + } + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========>hmac memory counter"); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s", + "op", "ap", "sta", "bss", "tap", "rap", "rap_eb", "scan_bss"); + ESP_LOGI(TAG, "%8s %8x %8x %8x %8x %8x %8x %8x", + "alloc", mem->ap_alloc, mem->sta_alloc, mem->bss_alloc, mem->tap_alloc, mem->rap_alloc, mem->rap_eb_alloc, mem->scan_bss_alloc); + ESP_LOGI(TAG, "%8s %8x %8x %8x %8x %8x %8x %8x", + "free", mem->ap_free, mem->sta_free, mem->bss_free, mem->tap_free, mem->rap_free, mem->rap_eb_free, mem->scan_bss_free); +} + +static void wifi_debug_dump_rx(const wifi_stats_optional_t *rx) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========>lmac rx counter"); + + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "r1_all", "r1_ampdu", "r1_mblk", "r1_dmpdu", "r1_mgmt", "r1_preq", "r1_bcn", "r1_bar", "r1_ba", "r1_psp"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->r1_all, rx->r1_ampdu, rx->r1_mutiple_blocks, rx->r1_data_mpdu, rx->r1_mgmt, rx->r1_mgmt_probe_req, + rx->r1_mgmt_beacon, rx->r1_ctrl_bar, rx->r1_ctrl_ba, rx->r1_ctrl_pspoll); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "r1_other","r1_mimo", "r1_drop", "r1d_if", "r1d_st", "r1d_type", "r1d_mblk", "r2d_mblk", "r2d_nmem", "r3d_tlon"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->r1_ctrl_others, rx->r1_sniffer_mimo, rx->r1_drop, rx->r1_drop_if_mismatch, rx->r1_drop_sniffer_state, rx->r1_drop_type_err, + rx->r1_drop_mpdu_multiple_blocks, rx->r2_drop_multiple_blocks, rx->r2_drop_mpdu_no_mem, rx->r3_drop_ampdu_too_long); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "r3d_tsht", "r3d_st", "r3d_nmem", "r3d_len", "r3d_ds", "r4d_apro", "r4d_mpro", "r4d_frag", "r4d_st", "r4d_tkip"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->r3_drop_ampdu_too_short, rx->r3_drop_ampdu_state, rx->r3_drop_ampdu_no_mem, rx->r3_drop_ampdu_len, rx->r3_drop_ampdu_ds, + rx->r4_drop_ampdu_proc, rx->r4_drop_mpdu_proc, rx->r4_drop_frag, rx->r4_drop_state, rx->r4_drop_tkipmic); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "r4d_sif", "r4d_aif", "r4d_if", "r5_amdu", "r5d_filt", "r5d_nmem", "r5d_qfai", "r6_mimo", "r6_sblk", "r6_mblk"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->r4_drop_sta_if, rx->r4_drop_ap_if, rx->r4_drop_if_mismatch, rx->r5_sniffer_ampdu, rx->r5_drop_sniffer_filter, + rx->r5_drop_sniffer_no_mem, rx->r5_drop_sniffer_q_fail, rx->r6_sniffer_mimo, rx->r6_sniffer_single_block, rx->r6_sniffer_multiple_blocks); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "r6d_flt", "r6d_nmem", "r6d_qfai", "r7_mimo", "r7d_nmem", "rd7_post", "r7d_oth", "r8_reset", "r8_relo", "h1d_cnul"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->r6_drop_sniffer_filter, rx->r6_drop_sniffer_no_mem, rx->r6_drop_sniffer_q_fail, rx->r7_sniffer_mimo, rx->r7_drop_sniffer_no_mem, + rx->r7_drop_sniffer_post, rx->r7_drop_sniffer_others, rx->r8_reset_rx_base, rx->r8_reload, rx->rh1_sta_drop_conn_null); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========>sta hmac rx counter"); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "h1d_ts", "h1d_ver", "h1d_bss", "h1d_mts", "h1d_inq", + "h1d_dup", "h1d_nass", "h1d_dtsh", "h1d_ds", "h1d_key"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->rh1_sta_drop_too_short, rx->rh1_sta_drop_wrong_version, rx->rh1_sta_drop_not_my_bss, rx->rh1_sta_drop_mgmt_too_short1, rx->rh1_sta_drop_mgmt_probe_inq, + rx->rh1_sta_drop_dup, rx->rh1_sta_drop_data_not_assoc, rx->rh1_sta_drop_data_too_short, rx->rh1_sta_drop_data_not_fromds, rx->rh1_sta_drop_data_invalid_key); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "h1d_frag", "h1d_mic", "h1d_enc", "h1d_nkey", "h1d_unen", "h1d_lwip", "h1_mgmt", "h1d_nods", "h1d_mts2", "h1d_bip"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->rh1_sta_drop_data_frag, rx->rh1_sta_drop_data_mic, rx->rh1_sta_drop_data_encap, rx->rh1_sta_drop_data_null_key, rx->rh1_sta_drop_data_unencrypt, + rx->rh1_sta_data_to_lwip, rx->rh1_sta_mgmt, rx->rh1_sta_drop_mgmt_not_nods, rx->rh1_sta_drop_mgmt_too_short2, rx->rh1_sta_drop_mgmt_bip_check); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "h2_wpss", "h2_wpsf", "h2d_wpsn", "h2d_1x", "h2d_neap", + "h2d_2eok", "h2d_2enl", "h2d_2est", "h2_wpas", "h2d_wpaf"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->rh2_sta_eapol_wps_succ, rx->rh2_sta_eapol_wps_fail, rx->rh2_sta_eapol_wps_null_handle, rx->rh2_sta_drop_not_8021x_auth, rx->rh2_sta_drop_not_allow_eapol, + rx->rh2_sta_eapol_wpa2e_succ, rx->rh2_sta_drop_eapol_wpa2e_null_handle, rx->rh2_sta_drop_eapol_wpa2e_state, rx->rh2_sta_eapol_wpa_succ, rx->rh2_sta_drop_eapol_wpa_fail); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "h2d_wpan", "h3_amsdu", "h3d_ts", "h3d_nmem", "h3d_rts", + "h3_samsdu", "h3_aamsdu", "h4_bcn", "h4_prsp", "h4_auth"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->rh2_sta_drop_eapol_wpa_null_handle, rx->rh3_data_amsdu, rx->rh3_drop_data_amsdu_too_short, rx->rh3_drop_data_amsdu_no_mem, rx->rh3_drop_data_amsdu_remain_too_short, + rx->rh3_sta_data_amsdu_mpdu, rx->rh3_ap_data_amsdu_mpdu, rx->rh4_sta_mgmt_beacon, rx->rh4_sta_mgmt_probe_resp, rx->rh4_sta_mgmt_auth); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "h4_death", "h4_assoc", "h4_ation", "h4d_unen", "h4d_nmy", + "h4d_munen", "h4d_disa", "h4d_munex", "h5_csa", "h5d_reg"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + rx->rh4_sta_mgmt_deauth, rx->rh4_sta_mgmt_assoc, rx->rh4_sta_mgmt_action, rx->rh4_sta_drop_mgmt_disassoc_unencrypt, rx->rh4_sta_drop_mgmt_disassoc_not_my, + rx->rh4_sta_drop_mgmt_unencrypt, rx->rh4_sta_mgmt_disassoc, rx->rh4_sta_drop_mgmt_unexpected, rx->rh5_sta_beacon_csa, rx->rh5_sta_drop_beacon_out_of_reg); + + ESP_LOGI(TAG, "========>ap hmac rx counter"); +} + +static void wifi_debug_dump_tx(const wifi_stats_optional_t *tx) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========>ap hmac rx counter"); + + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "t1_enwq", "t1d_sec", "t1d_eqf", "t1d_stop", "t2_atm", + "t3_ewq", "t4_dql", "t4_wql", "t4_wq1l", "t4_rxql", "post_of", "post_f"); + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + tx->t1_en_waitq, tx->t1_drop_sec, tx->t1_drop_enq_fail, tx->t1_drop_stop, tx->t2_ampdu_to_mpdu, + tx->t3_en_waitq, tx->t4_doneq_len, tx->t4_waitq0_len, tx->t4_waitq1_len, tx->t4_rxq_len, + tx->pp_post_overflow, tx->pp_post_fail, tx->t10_complete_invalid_state); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%3s %3s %3s %3s %3s %3s %3s %3s %3s %3s %3s %3s %3s %3s %3s %3s", + "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"); + ESP_LOGI(TAG, "%3x %3x %3x %3x %3x %3x %3x %3x %3x %3x %3x %3x %3x %3x %3x %3x", + tx->t4_qlen[0], tx->t4_qlen[1], tx->t4_qlen[2], tx->t4_qlen[3], tx->t4_qlen[4], tx->t4_qlen[5], tx->t4_qlen[6], tx->t4_qlen[7], + tx->t4_qlen[8], tx->t4_qlen[9], tx->t4_qlen[10], tx->t4_qlen[11], tx->t4_qlen[12], tx->t4_qlen[13], tx->t4_qlen[14], tx->t4_qlen[15]); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%16s %8s %8s %8s %8s %8s %8s", + "type", "ac0", "ac1", "ac2", "ac3", "ac4", "ac5"); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t5_drop_aged", tx->t5_drop_aged[0], tx->t5_drop_aged[1], tx->t5_drop_aged[2], tx->t5_drop_aged[3], tx->t5_drop_aged[4], tx->t5_drop_aged[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t6_succ", tx->t6_succ[0], tx->t6_succ[1], tx->t6_succ[2], tx->t6_succ[3], tx->t6_succ[4], tx->t6_succ[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t7_drop_src", tx->t7_drop_src[0], tx->t7_drop_src[1], tx->t7_drop_src[2], tx->t7_drop_src[3], tx->t7_drop_src[4], tx->t7_drop_src[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t7_drop_lrc", tx->t7_drop_lrc[0], tx->t7_drop_lrc[1], tx->t7_drop_lrc[2], tx->t7_drop_lrc[3], tx->t7_drop_lrc[4], tx->t7_drop_lrc[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t7_drop_others", tx->t7_drop_others[0], tx->t7_drop_others[1], tx->t7_drop_others[2], tx->t7_drop_others[3], tx->t7_drop_others[4], tx->t7_drop_others[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t8_drop_src", tx->t8_drop_src[0], tx->t8_drop_src[1], tx->t8_drop_src[2], tx->t8_drop_src[3], tx->t8_drop_src[4], tx->t8_drop_src[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t8_drop_lrc", tx->t8_drop_lrc[0], tx->t8_drop_lrc[1], tx->t8_drop_lrc[2], tx->t8_drop_lrc[3], tx->t8_drop_lrc[4], tx->t8_drop_lrc[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t8_drop_others", tx->t8_drop_others[0], tx->t8_drop_others[1], tx->t8_drop_others[2], tx->t8_drop_others[3], tx->t8_drop_others[4], tx->t8_drop_others[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t9_drop_src", tx->t9_drop_src[0], tx->t9_drop_src[1], tx->t9_drop_src[2], tx->t9_drop_src[3], tx->t9_drop_src[4], tx->t9_drop_src[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t9_drop_lrc", tx->t9_drop_lrc[0], tx->t9_drop_lrc[1], tx->t9_drop_lrc[2], tx->t9_drop_lrc[3], tx->t9_drop_lrc[4], tx->t9_drop_lrc[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t9_drop_others", tx->t9_drop_others[0], tx->t9_drop_others[1], tx->t9_drop_others[2], tx->t9_drop_others[3], tx->t9_drop_others[4], tx->t9_drop_others[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t10_com_succ", tx->t10_complete_succ[0], tx->t10_complete_succ[1], tx->t10_complete_succ[2], tx->t10_complete_succ[3], tx->t10_complete_succ[4], tx->t10_complete_succ[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t10_com_cts", tx->t10_complete_cts_err[0], tx->t10_complete_cts_err[1], tx->t10_complete_cts_err[2], tx->t10_complete_cts_err[3], tx->t10_complete_cts_err[4], tx->t10_complete_cts_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t10_com_ack", tx->t10_complete_ack_err[0], tx->t10_complete_ack_err[1], tx->t10_complete_ack_err[2], tx->t10_complete_ack_err[3], tx->t10_complete_ack_err[4], tx->t10_complete_ack_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t10_com_data", tx->t10_complete_data_err[0], tx->t10_complete_data_err[1], tx->t10_complete_data_err[2], tx->t10_complete_data_err[3], tx->t10_complete_data_err[4], tx->t10_complete_data_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t10_com_other", tx->t10_complete_other_err[0], tx->t10_complete_other_err[1], tx->t10_complete_other_err[2], tx->t10_complete_other_err[3], tx->t10_complete_other_err[4], tx->t10_complete_other_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t11_timeout", tx->t11_timeout[0], tx->t11_timeout[1], tx->t11_timeout[2], tx->t11_timeout[3], tx->t11_timeout[4], tx->t11_timeout[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t12_collision", tx->t12_collision[0], tx->t12_collision[1], tx->t12_collision[2], tx->t12_collision[3], tx->t12_collision[4], tx->t12_collision[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t13_com_rts", tx->t13_complete_rts_collision_err[0], tx->t13_complete_rts_collision_err[1], tx->t13_complete_rts_collision_err[2], tx->t13_complete_rts_collision_err[3], tx->t13_complete_rts_collision_err[4], tx->t13_complete_rts_collision_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t13_com_rtsseck", tx->t13_complete_rts_seckid_err[0], tx->t13_complete_rts_seckid_err[1], tx->t13_complete_rts_seckid_err[2], tx->t13_complete_rts_seckid_err[3], tx->t13_complete_rts_seckid_err[4], tx->t13_complete_rts_seckid_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t14_com_data", tx->t14_complete_data_collision_err[0], tx->t14_complete_data_collision_err[1], tx->t14_complete_data_collision_err[2], tx->t14_complete_data_collision_err[3], tx->t14_complete_data_collision_err[4], tx->t14_complete_data_collision_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t14_com_dseckid", tx->t14_complete_data_seckid_err[0], tx->t14_complete_data_seckid_err[1], tx->t14_complete_data_seckid_err[2], tx->t14_complete_data_seckid_err[3], tx->t14_complete_data_seckid_err[4], tx->t14_complete_data_seckid_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t14_com_dzero", tx->t14_complete_data_zero_err[0], tx->t14_complete_data_zero_err[1], tx->t14_complete_data_zero_err[2], tx->t14_complete_data_zero_err[3], tx->t14_complete_data_zero_err[4], tx->t14_complete_data_zero_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t14_com_dother", tx->t14_complete_data_other_err[0], tx->t14_complete_data_other_err[1], tx->t14_complete_data_other_err[2], tx->t14_complete_data_other_err[3], tx->t14_complete_data_other_err[4], tx->t14_complete_data_other_err[5]); + ESP_LOGI(TAG, "%16s %8x %8x %8x %8x %8x %8x", + "t15_send_bar", tx->t15_send_bar[0], tx->t15_send_bar[1], tx->t15_send_bar[2], tx->t15_send_bar[3], tx->t15_send_bar[4], tx->t15_send_bar[5]); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "ifx", "data_all", "arp", "raw", "dhcp", "ps_q", + "drop_arg", "drop_if", "drop_all", "drop_nul", "drop_run"); + ESP_LOGI(TAG, "%8s %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + "sta", tx->tx[0].tx_data_all, tx->tx[0].tx_arp, tx->tx[0].tx_raw, tx->tx[0].tx_dhcp, tx->tx[0].tx_ps_q, + tx->tx[0].tx_drop_data_arg, tx->tx[0].tx_drop_data_if, tx->tx[0].tx_drop_data_all, tx->tx[0].tx_drop_data_conn_null, tx->tx[0].tx_drop_data_not_run); + ESP_LOGI(TAG, "%8s %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + "ap", tx->tx[1].tx_data_all, tx->tx[1].tx_arp, tx->tx[1].tx_raw, tx->tx[1].tx_dhcp, tx->tx[1].tx_ps_q, + tx->tx[1].tx_drop_data_arg, tx->tx[1].tx_drop_data_if, tx->tx[1].tx_drop_data_all, tx->tx[1].tx_drop_data_conn_null, tx->tx[1].tx_drop_data_not_run); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "ifx", "drop_asso", "drop_ath", "drop_nme", "drop_qfu", "drop_pfl", "drop_buf", + "drop_ps", "yield", "not_home", "nh_free", "nh_scan"); + ESP_LOGI(TAG, "%8s %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + "sta", tx->tx[0].tx_drop_data_not_assoc, tx->tx[0].tx_drop_data_not_auth, tx->tx[0].tx_drop_data_no_mem, + tx->tx[0].tx_drop_data_qfull, tx->tx[0].tx_drop_data_post_fail, tx->tx[0].tx_drop_data_buf, tx->tx[0].tx_drop_data_ps, + tx->tx[0].tx_task_yield, tx->tx[0].tx_buffer_not_home_chan, tx->tx[0].tx_buffer_not_home_chan_free, tx->tx[0].tx_buffer_not_home_chan_scan); + ESP_LOGI(TAG, "%8s %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + "ap", tx->tx[1].tx_drop_data_not_assoc, tx->tx[1].tx_drop_data_not_auth, tx->tx[1].tx_drop_data_no_mem, + tx->tx[1].tx_drop_data_qfull, tx->tx[1].tx_drop_data_post_fail, tx->tx[1].tx_drop_data_buf, tx->tx[1].tx_drop_data_ps, + tx->tx[1].tx_task_yield, tx->tx[1].tx_buffer_not_home_chan, tx->tx[1].tx_buffer_not_home_chan_free, tx->tx[1].tx_buffer_not_home_chan_scan); +} + +static void wifi_debug_dump_sleep(const wifi_stats_optional_t *pm) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========> PM counter"); + + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %8s %8s %8s", + "bnc_invl", "dtim", "listen", "tbtt", "rx_bcn", "act_to", "wake_tx", "wake_tbt", "wake_tim", "wake_dtim"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %8x %8x %8x", + pm->pm_bcn_interval, pm->pm_dtim_period, pm->pm_listen_interval, pm->pm_tbtt, pm->pm_rx_bcn, + pm->pm_active_timeout, pm->pm_wake_tx, pm->pm_wake_tbtt, pm->pm_wake_tim, pm->pm_wake_dtim); + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%8s %8s %8s %8s %8s %8s %8s %16s %16s %16s", + "slp_null", "wake_nul", "sleep", "wake", "bcn_dlay", + "maxb_dl", "avgb_dl", "sleep_t", "wake_t", "total_t"); + ESP_LOGI(TAG, "%8x %8x %8x %8x %8x %8x %8x %16llx %16llx %16llx", + pm->pm_sleep_null, pm->pm_wake_null, pm->pm_sleep, pm->pm_wake, pm->pm_bcn_delay_time, + pm->pm_max_bcn_delay_time, pm->pm_avg_bcn_delay_time, pm->pm_sleep_time, pm->pm_wake_time, pm->pm_total_time); + +} + +void esp_wifi_dump_stats(const wifi_stats_t *stats, uint64_t modules) +{ + if (modules & WIFI_MODULE_HW_DIAG) { + wifi_debug_dump_diag(&stats->mandatory.reg.diag); + } + + if (modules & WIFI_MODULE_HW_COUNTERS) { + wifi_debug_dump_cnt(&stats->mandatory.reg.cnt); + } + + if (modules & WIFI_MODULE_HW_MISC) { + wifi_debug_dump_misc(&stats->mandatory.reg.misc); + } + + if (modules & WIFI_MODULE_INT_COUNTERS) { + wifi_debug_dump_int(&stats->mandatory.interrupt); + } + + if (modules & WIFI_MODULE_BUFFER_COUNTERS) { + wifi_debug_dump_buf(stats); + } + + if (modules & WIFI_MODULE_RX_COUNTERS) { + wifi_debug_dump_rx(&stats->optional); + } + + if (modules & WIFI_MODULE_TX_COUNTERS) { + wifi_debug_dump_tx(&stats->optional); + } + + if (modules & WIFI_MODULE_SLEEP) { + wifi_debug_dump_sleep(&stats->optional); + } + + if (modules & WIFI_MODULE_SLEEP) { + wifi_debug_dump_sleep(&stats->optional); + } +} + +void esp_wifi_dump(uint64_t modules) +{ + if (modules == 0) { + return; + } + + wifi_stats_t *stats = (wifi_stats_t*)wifi_malloc(sizeof(wifi_stats_t)); + + if (!stats) { + ESP_LOGE(TAG, "poll request: fail allocate wifi stats"); + return; + } + + esp_wifi_stats_get(stats); + esp_wifi_dump_stats(stats, modules); + free(stats); +} diff --git a/components/esp32/wifi_init.c b/components/esp32/wifi_init.c index 01c5de48a2..36c0ec99b8 100644 --- a/components/esp32/wifi_init.c +++ b/components/esp32/wifi_init.c @@ -19,6 +19,7 @@ #include "esp_pm.h" #include "soc/rtc.h" #include "esp_mesh.h" +#include "esp_debug.h" #if (CONFIG_ESP32_WIFI_RX_BA_WIN > CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM) #error "WiFi configuration check: WARNING, WIFI_RX_BA_WIN should not be larger than WIFI_DYNAMIC_RX_BUFFER_NUM!" @@ -120,6 +121,7 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) s_wifi_mac_time_update_cb = esp_wifi_internal_update_mac_time; } + esp_debug_init(); return result; } diff --git a/components/esp_debug/CMakeLists.txt b/components/esp_debug/CMakeLists.txt new file mode 100644 index 0000000000..71db21e12a --- /dev/null +++ b/components/esp_debug/CMakeLists.txt @@ -0,0 +1,13 @@ +idf_build_get_property(target IDF_TARGET) + +set(srcs "src/esp_debug.c") + +set(include_dirs + lwip/port/esp32/include + ) + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS include + PRIV_INCLUDE_DIRS + REQUIRES esp_event lwip + PRIV_REQUIRES "${target}") diff --git a/components/esp_debug/Kconfig b/components/esp_debug/Kconfig new file mode 100644 index 0000000000..a120a124df --- /dev/null +++ b/components/esp_debug/Kconfig @@ -0,0 +1,228 @@ +menu "ESP DEBUG" + +config ESP32_WIFI_DEBUG_COUNTER + bool "Enable WiFi Debug Counter" + default n + help + Select this option to enable more debug counters + +config ESP32_WIFI_DEBUG_PKT_FILTER_ENABLE + bool "Enable WiFi Packet Filter " + default n + help + Select this option to enable WiFi packet filter + +menu "WiFi Packet Filter Type" + depends on ESP32_WIFI_DEBUG_PKT_FILTER_ENABLE + +config ESP32_WIFI_DEBUG_PKT_FILTER_TCP + bool "Filter TCP Packets" + default n + help + Select this option to filter TCP packets. + +config ESP32_WIFI_DEBUG_PKT_FILTER_UDP + bool "Filter UDP Packets" + default n + help + Select this option to filter UDP packets. + +config ESP32_WIFI_DEBUG_PKT_FILTER_ARP + bool "Filter ARP Packets" + default n + help + Select this option to filter ARP packets. + +config ESP32_WIFI_DEBUG_PKT_FILTER_DHCP + bool "Filter DHCP Packets" + default n + help + Select this option to filter DHCP packets. + +config ESP32_WIFI_DEBUG_PKT_FILTER_DNS + bool "Filter DNS Packets" + default n + help + Select this option to filter DNS packets. + +config ESP32_WIFI_DEBUG_PKT_FILTER_MDNS + bool "Filter MDNS Packets" + default n + help + Select this option to filter DNS packets. + +endmenu + + +config ESP32_DEBUG_TASK_ENABLE + bool "Enable Debug Polling Task" + default n + help + Select this option to create debug task. +config ESP32_DEBUG_TASK_PRIORITY + int "Debug Task priority" + depends on ESP32_DEBUG_TASK_ENABLE + range 1 23 + default 10 + help + Set WiFi debug task priority + +config ESP32_DEBUG_TASK_STACK_SIZE + int "Debug Task Stack Size" + depends on ESP32_DEBUG_TASK_ENABLE + default 3072 + range 1024 65536 + help + Configure WiFi debug task stack size. + +config ESP32_DEBUG_TASK_POLLING_ENABLE + bool "Enable Debug Task Polling" + depends on ESP32_DEBUG_TASK_ENABLE + default n + help + Select this option to enable Debug Task Polling. + + When the polling is enabled, the Debug Task query and dump the specified counters periodically. + +config ESP32_DEBUG_TASK_POLLING_PERIOD + int "Debug Task Polling Period (seconds)" + depends on ESP32_DEBUG_TASK_POLLING_ENABLE + range 1 65535 + default 30 + help + Select this option to enable Debug Task Polling + +menu "WiFi Polling Modules" +depends on ESP32_DEBUG_TASK_POLLING_ENABLE + +config ESP32_DEBUG_TASK_POLLING_WIFI_HARDWARE_DIAG + bool "Polling WiFi hardware diag registers" + default n + help + Select this option to polling WiFi hardware diag registers + +config ESP32_DEBUG_TASK_POLLING_WIFI_HARDWARE_COUNTERS + bool "Polling WiFi hardware counters" + default n + help + Select this option to polling WiFi hardware counters + +config ESP32_DEBUG_TASK_POLLING_WIFI_HARDWARE_MISC + bool "Polling WiFi hardware misc registers" + default n + help + Select this option to polling WiFi hardware misc registers + +config ESP32_DEBUG_TASK_POLLING_WIFI_BUFFER_COUNTERS + bool "Polling WiFi buffer counters" + default y + help + Select this option to polling WiFi buffer counters + +config ESP32_DEBUG_TASK_POLLING_WIFI_INT_COUNTERS + bool "Polling WiFi interrupt counters" + default y + help + Select this option to polling WiFi interrupt counters + + +config ESP32_DEBUG_TASK_POLLING_WIFI_RX_COUNTERS + bool "Polling WiFi receiving packet counters" + default y + help + Select this option to polling WiFi receiving packet counters + +config ESP32_DEBUG_TASK_POLLING_WIFI_TX_COUNTERS + bool "Polling WiFi transmitting packet counters" + default y + help + Select this option to polling WiFi transmitting packet counters + +config ESP32_DEBUG_TASK_POLLING_WIFI_BUFFER_COUNTERS + bool "Polling WiFi buffer counters" + default y + help + Select this option to polling WiFi buffer counters + +config ESP32_DEBUG_TASK_POLLING_WIFI_SLEEP_COUNTERS + bool "Polling WiFi sleep counters" + default y + help + Select this option to polling WiFi sleep counters + +config ESP32_DEBUG_TASK_POLLING_WIFI_EVENT_COUNTERS + bool "Polling WiFi event counters" + default n + help + Select this option to polling WiFi key event counters + +config ESP32_DEBUG_TASK_POLLING_WIFI_NVS_INFO + bool "Polling WiFi NVS info" + default n + help + Select this option to polling WiFi NVS info + +config ESP32_DEBUG_TASK_POLLING_WIFI_STA_INFO + bool "Polling WiFi station internal info" + default n + help + Select this option to polling WiFi station internal info + +config ESP32_DEBUG_TASK_POLLING_WIFI_AP_INFO + bool "Polling WiFi soft-AP internal info" + default n + help + Select this option to polling WiFi soft-AP internal info + +config ESP32_DEBUG_TASK_POLLING_WIFI_TRC_INFO + bool "Polling WiFi rate control info" + default n + help + Select this option to polling WiFi rate control info + + +config ESP32_DEBUG_TASK_POLLING_WIFI_MEMORY_INFO + bool "Polling WiFi memory info" + default n + help + Select this option to polling WiFi memory info + + +endmenu +menu "LWIP Polling Modules" +depends on ESP32_DEBUG_TASK_POLLING_ENABLE + +config ESP32_DEBUG_TASK_POLLING_LWIP_SOCKETS + bool "Polling LWIP sockets info" + default n + help + Select this option to polling WiFi memory info + +config ESP32_DEBUG_TASK_POLLING_LWIP_PKT_COUNTER + bool "Polling LWIP packet counters" + default n + help + Select this option to polling LWIP packet counters +endmenu +menu "System Polling Modules" +depends on ESP32_DEBUG_TASK_POLLING_ENABLE + +config ESP32_DEBUG_TASK_POLLING_TASK_INFO + bool "Polling task info" + default n + help + Select this option to polling LWIP packet counters + +config ESP32_DEBUG_TASK_POLLING_MEMORY_INFO + bool "Polling memory info" + default n + help + Select this option to polling memory info + +endmenu + + +endmenu + + + diff --git a/components/esp_debug/Makefile.projbuild b/components/esp_debug/Makefile.projbuild new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/esp_debug/component.mk b/components/esp_debug/component.mk new file mode 100644 index 0000000000..67a99bb587 --- /dev/null +++ b/components/esp_debug/component.mk @@ -0,0 +1,5 @@ +# +# Component Makefile +# +COMPONENT_SRCDIRS := src +COMPONENT_PRIV_INCLUDEDIRS := private_include diff --git a/components/esp_debug/include/esp_debug.h b/components/esp_debug/include/esp_debug.h new file mode 100644 index 0000000000..a385104244 --- /dev/null +++ b/components/esp_debug/include/esp_debug.h @@ -0,0 +1,100 @@ +// Copyright 2020-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + * All the APIs declared here are internal only APIs, it can only be used by + * espressif internal modules, such as SSC, LWIP, TCPIP adapter etc, espressif + * customers are not recommended to use them. + * + * If someone really want to use specified APIs declared in here, please contact + * espressif AE/developer to make sure you know the limitations or risk of + * the API, otherwise you may get unexpected behavior!!! + * + */ + + +#ifndef __ESP_DEBUG_H__ +#define __ESP_DEBUG_H__ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "sys/queue.h" +#include "esp_err.h" +#include "esp_event.h" +#include "esp_wifi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t diag; +} wifi_hardware_diag_t; + +void esp_wifi_debug_get_hardare_diag(wifi_hardware_diag_t *reg); +void esp_wifi_debug_dump_hardware_diag(const wifi_hardware_diag_t *reg); + +typedef struct { +} wifi_int_counter_t; +void esp_wifi_debug_get_int_counter(wifi_int_counter_t *cnt); +void esp_wifi_debug_dump_int_counter(const wifi_int_counter_t *cnt); + +/* Polling type definition + * - bit0 is for debug task deleting + * - bit1~15 is for system info polling + * - bit16~31 is for LWIP info polling + * - bit32~63 is for WiFi info polling + */ +#define DEBUG_MODULE_TASK_DELETE 1 + +#define DEBUG_MODULE_SYS_MEM (1ULL<<1) +#define DEBUG_MODULE_SYS_TASK (1ULL<<2) + +#define DEBUG_MODULE_LWIP_SOCKETS (1ULL<<16) +#define DEBUG_MODULE_LWIP_STATS (1ULL<<17) + +#define DEBUG_MODULE_WIFI_HW_DIAG (1ULL<<32) +#define DEBUG_MODULE_WIFI_HW_COUNTERS (1ULL<<33) +#define DEBUG_MODULE_WIFI_HW_MISC (1ULL<<34) +#define DEBUG_MODULE_WIFI_INT_COUNTERS (1ULL<<35) +#define DEBUG_MODULE_WIFI_RX_COUNTERS (1ULL<<36) +#define DEBUG_MODULE_WIFI_TX_COUNTERS (1ULL<<37) +#define DEBUG_MODULE_WIFI_BUFFER_COUNTERS (1ULL<<38) +#define DEBUG_MODULE_WIFI_SLEEP_COUNTERS (1ULL<<39) +#define DEBUG_MODULE_WIFI_EVENT_COUNTERS (1ULL<<40) +#define DEBUG_MODULE_WIFI_NVS (1ULL<<41) +#define DEBUG_MODULE_WIFI_STA (1ULL<<42) +#define DEBUG_MODULE_WIFI_AP (1ULL<<43) +#define DEBUG_MODULE_WIFI_TRC (1ULL<<44) + +#define DEBUG_MODULE_ALL (0xFFFFFFFFFFFFFFFE) + +typedef uint64_t wifi_polling_request_t; + +void esp_lwip_debug_dump_sockets(void); +void esp_lwip_debug_dump_stats(void); +void esp_lwip_dump(uint64_t modules); + +esp_err_t esp_debug_init(void); +esp_err_t esp_debug_deinit(void); + +esp_err_t esp_debug_poll(wifi_polling_request_t request); + +#ifdef __cplusplus +} +#endif + +#endif /* __WIFI_DEBUG_H__ */ diff --git a/components/esp_debug/src/esp_debug.c b/components/esp_debug/src/esp_debug.c new file mode 100644 index 0000000000..e241112c2e --- /dev/null +++ b/components/esp_debug/src/esp_debug.c @@ -0,0 +1,359 @@ +// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include "esp_log.h" +#include "esp_wifi_internal.h" +#include "esp_debug.h" +#include "wifi_debug.h" + +#define TAG "wdbg" + +static bool s_debug_init = false; + +#if CONFIG_ESP32_DEBUG_TASK_ENABLE +#define WIFI_DEBUG_TASK_QUEUE_SIZE 5 +static SemaphoreHandle_t s_debug_mutex = NULL; +static QueueHandle_t s_debug_task_queue = NULL; +static bool s_debug_task_init = false; + +void debug_lock(void) +{ + if (s_debug_mutex) { + xSemaphoreTake(s_debug_mutex, portMAX_DELAY); + } else { + s_debug_mutex = xSemaphoreCreateMutex(); + if (!s_debug_mutex) { + ESP_LOGE(TAG, "fail to create mutex"); + abort(); + } else { + xSemaphoreTake(s_debug_mutex, portMAX_DELAY); + } + } +} + +void debug_unlock(void) +{ + if (s_debug_mutex) { + xSemaphoreGive(s_debug_mutex); + } else { + ESP_LOGE(TAG, "unlock null mutex"); + abort(); + } +} + +static uint64_t debug_periodical_request(void) +{ + uint64_t request = 0; + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_LWIP_SOCKETS + request |= DEBUG_MODULE_LWIP_SOCKETS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_LWIP_STATS + request |= DEBUG_MODULE_LWIP_STATISTICS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_HARDWARE_DIAG + request |= DEBUG_MODULE_WIFI_HW_DIAG; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_HARDWARE_COUNTERS + request |= DEBUG_MODULE_WIFI_HW_COUNTERS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_HARDWARE_MISC + request |= DEBUG_MODULE_WIFI_HW_MISC; +#endif + + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_INT_COUNTERS + request |= DEBUG_MODULE_WIFI_INT_COUNTERS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_RX_COUNTERS + request |= DEBUG_MODULE_WIFI_RX_COUNTERS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_TX_COUNTERS + request |= DEBUG_MODULE_WIFI_TX_COUNTERS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_BUFFER_COUNTERS + request |= DEBUG_MODULE_WIFI_BUFFER_COUNTERS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_SLEEP_COUNTERS + request |= DEBUG_MODULE_WIFI_SLEEP_COUNTERS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_EVENT_COUNTERS + request |= DEBUG_MODULE_WIFI_EVENT_COUNTERS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_NVS_INFO + request |= DEBUG_MODULE_WIFI_NVS; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_STA_INFO + request |= DEBUG_MODULE_WIFI_STA; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_AP_INFO + request |= DEBUG_MODULE_WIFI_AP; +#endif + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_WIFI_TRC_INFO + request |= DEBUG_MODULE_WIFI_TRC; +#endif + return request; +} + +static uint64_t debug_modules_to_lwip_modules(uint64_t modules) +{ + uint64_t lwip_modules = 0; + + if (modules & DEBUG_MODULE_LWIP_SOCKETS) { + lwip_modules |= 1;//LWIP_MODULE_SOCKETS; + } + + if (modules & DEBUG_MODULE_LWIP_STATS) { + lwip_modules |= 1<<1;//LWIP_MODULE_STATS; + } + + return lwip_modules; +} + +static uint64_t debug_modules_to_wifi_modules(uint64_t modules) +{ + uint64_t wifi_modules = 0; + + if (modules & DEBUG_MODULE_WIFI_HW_DIAG) { + wifi_modules |= WIFI_MODULE_HW_DIAG; + } + + if (modules & DEBUG_MODULE_WIFI_HW_COUNTERS) { + wifi_modules |= WIFI_MODULE_HW_COUNTERS; + } + + if (modules & DEBUG_MODULE_WIFI_INT_COUNTERS) { + wifi_modules |= WIFI_MODULE_INT_COUNTERS; + } + + if (modules & DEBUG_MODULE_WIFI_RX_COUNTERS) { + wifi_modules |= WIFI_MODULE_RX_COUNTERS; + } + + if (modules & DEBUG_MODULE_WIFI_TX_COUNTERS) { + wifi_modules |= WIFI_MODULE_TX_COUNTERS; + } + + if (modules & DEBUG_MODULE_WIFI_BUFFER_COUNTERS) { + wifi_modules |= WIFI_MODULE_BUFFER_COUNTERS; + } + + if (modules & DEBUG_MODULE_WIFI_SLEEP_COUNTERS) { + wifi_modules |= WIFI_MODULE_SLEEP; + } + + if (modules & DEBUG_MODULE_WIFI_EVENT_COUNTERS) { + wifi_modules |= WIFI_MODULE_EVENT_COUNTERS; + } + + if (modules & DEBUG_MODULE_WIFI_NVS) { + wifi_modules |= WIFI_MODULE_NVS; + } + + if (modules & DEBUG_MODULE_WIFI_STA) { + wifi_modules |= WIFI_MODULE_STA; + } + + if (modules & DEBUG_MODULE_WIFI_AP) { + wifi_modules |= WIFI_MODULE_AP; + } + + if (modules & DEBUG_MODULE_WIFI_TRC) { + wifi_modules |= WIFI_MODULE_TRC; + } + + return wifi_modules; +} + +static void debug_process_request(wifi_polling_request_t request) +{ + uint64_t modules = 0; + + ESP_LOGI(TAG, "poll begin, type=%llx, ram=%d mini=%d", request, esp_get_free_heap_size(), esp_get_minimum_free_heap_size()); + + modules = debug_modules_to_lwip_modules(request); + esp_lwip_dump(modules); + + modules = debug_modules_to_wifi_modules(request); + esp_wifi_dump(modules); + + ESP_LOGI(TAG, "poll end, ram=%d mini=%d", esp_get_free_heap_size(), esp_get_minimum_free_heap_size()); +} + +static void debug_task(void *param) +{ + wifi_polling_request_t request = 0; + uint32_t timeout = portMAX_DELAY; + +#if CONFIG_ESP32_DEBUG_TASK_POLLING_ENABLE + timeout = (CONFIG_ESP32_DEBUG_TASK_POLLING_PERIOD * 1000) / portTICK_RATE_MS; +#endif + + while (1) { + if (pdTRUE != xQueueReceive(s_debug_task_queue, &request, timeout)) { + request = debug_periodical_request(); + } + + debug_process_request(request); + + if (request == DEBUG_MODULE_TASK_DELETE) { + break; + } + } + + vQueueDelete(s_debug_task_queue); + s_debug_task_queue = NULL; + vTaskDelete(NULL); +} + +esp_err_t debug_task_create(void) +{ + int ret; + + debug_lock(); + if (s_debug_task_init == true) { + ESP_LOGE(TAG, "wifi init task already created"); + debug_unlock(); + return ESP_OK; + } + + s_debug_task_queue = xQueueCreate(WIFI_DEBUG_TASK_QUEUE_SIZE, sizeof(wifi_polling_request_t)); + if (!s_debug_task_queue) { + ESP_LOGE(TAG, "fail to create debug task queue"); + debug_unlock(); + return ESP_FAIL; + } + + ret = xTaskCreate(debug_task, "wifi_debug", CONFIG_ESP32_DEBUG_TASK_STACK_SIZE, NULL, CONFIG_ESP32_DEBUG_TASK_PRIORITY, NULL); + if (pdTRUE != ret) { + ESP_LOGE(TAG, "fail to create debug task"); + vQueueDelete(s_debug_task_queue); + s_debug_task_queue = NULL; + debug_unlock(); + return ESP_FAIL; + } + + s_debug_task_init = true; + debug_unlock(); + ESP_LOGI(TAG, "wifi debug task created"); + return ESP_OK; +} + +static void debug_task_delete(void) +{ + wifi_polling_request_t request = DEBUG_MODULE_TASK_DELETE; + + debug_lock(); + if (false == s_debug_task_init) { + ESP_LOGI(TAG, "wifi debug task already deleted"); + debug_unlock(); + return; + } + + //post delete event to WiFi debug task with blocking + xQueueSend(s_debug_task_queue, &request, portMAX_DELAY); + + /* Wait until debug task is deleted */ + do { + vTaskDelay(1); + } while (s_debug_task_queue); + + s_debug_task_init = false; + debug_unlock(); + ESP_LOGI(TAG, "wifi debug task deleted"); + return; +} + +esp_err_t esp_debug_poll(wifi_polling_request_t request) +{ + debug_lock(); + + if (false == s_debug_task_init) { + ESP_LOGE(TAG, "wifi debug task not created"); + debug_unlock(); + return ESP_FAIL; + } + + //post event to WiFi debug task without any blocking + if (pdTRUE != xQueueSend(s_debug_task_queue, &request, 0) ) { + ESP_LOGW(TAG, "failed to post polling event=%llx", request); + } + + debug_unlock(); + return ESP_OK; +} +#else +esp_err_t esp_debug_poll(wifi_polling_request_t request) +{ + ESP_LOGE(TAG, "poll disabled"); + return ESP_OK; +} +#endif + +esp_err_t esp_debug_init(void) +{ + esp_err_t ret = ESP_OK; + + if (true == s_debug_init) { + return ESP_OK; + } + + // TODO Set Packets Filter + + ret = esp_wifi_stats_init(); + if (ESP_OK != ret) { + return ESP_FAIL; + } + +#if CONFIG_ESP32_DEBUG_TASK_ENABLE + //Create polling task + ret = debug_task_create(); + if (ESP_OK != ret) { + esp_wifi_stats_deinit(); + return ESP_FAIL; + } +#endif + s_debug_init = true; + return ESP_OK; +} + +esp_err_t esp_debug_deinit(void) +{ + if (false == s_debug_init) { + return ESP_OK; + } + + esp_wifi_stats_deinit(); +#if CONFIG_ESP32_DEBUG_TASK_ENABLE + debug_task_delete(); +#endif + s_debug_init = false; + return ESP_OK; +} + diff --git a/components/lwip/lwip b/components/lwip/lwip index f8e38d3f60..68ba3db3f1 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit f8e38d3f607a0965a0e6070b7f12d2da336cc0c7 +Subproject commit 68ba3db3f10a69467c38d0352e887de985f30184 diff --git a/components/lwip/port/esp32/debug/lwip_debug.c b/components/lwip/port/esp32/debug/lwip_debug.c index 8e1574548c..849ef37b2c 100644 --- a/components/lwip/port/esp32/debug/lwip_debug.c +++ b/components/lwip/port/esp32/debug/lwip_debug.c @@ -22,194 +22,860 @@ #include "lwip/priv/memp_priv.h" #include "lwip/memp.h" #include "esp_log.h" +#include "freertos/task.h" +#include "string.h" +#include "lwip/tcpip.h" +#include "lwip/priv/sockets_priv.h" -#define DBG_LWIP_IP_SHOW(info, ip) ESP_LWIP_LOGI("%s type=%d ip=%x", (info), (ip).type, (ip).u_addr.ip4.addr) -#define DBG_LWIP_IP_PCB_SHOW(pcb) \ - DBG_LWIP_IP_SHOW("local ip", (pcb)->local_ip);\ - DBG_LWIP_IP_SHOW("remote ip", (pcb)->local_ip);\ - ESP_LWIP_LOGI("so_options=%x, tos=%d ttl=%d", (pcb)->so_options, (pcb)->tos, (pcb)->ttl) - -#define DBG_LWIP_SEG_SHOW(seg) while(seg) { ESP_LWIP_LOGI("\tseg=%p next=%p pbuf=%p flags=%x", (seg), (seg)->next, (seg)->p, (seg)->flags); (seg)=(seg)->next;} -#define DBG_LWIP_ITEM_NUMBER_PER_LINE 9 - -#if ESP_STATS_TCP -static void dbg_lwip_tcp_pcb_cnt_show(struct tcp_pcb *pcb) -{ - int len = 0; - char *buf; - char *p; - int i; - - buf = mem_malloc(512); - if (!buf) { - return; - } - - p = buf; - len += sprintf(p + len, "%11s", "tcp_retry: "); - for (i=0; iretry_cnt[i]); - } - ESP_LWIP_LOGI("%s", buf); - p = buf; - len = 0; - len += sprintf(p + len, "%11s", "tcp_rto#0:"); - for (i=0; irto_cnt[i]); - } - ESP_LWIP_LOGI("%s", buf); - - free(buf); -} -#endif - -static void dbg_lwip_tcp_pcb_one_show(struct tcp_pcb* pcb) -{ - struct tcp_seg *seg = NULL; - - if (!pcb) { - return; - } - - ESP_LWIP_LOGI("pcb=%p next=%p cb_arg=%p", pcb, pcb->next, pcb->callback_arg); - DBG_LWIP_IP_PCB_SHOW(pcb); - ESP_LWIP_LOGI("state=%x", pcb->state); - ESP_LWIP_LOGI("prio=%d", pcb->prio); - ESP_LWIP_LOGI("local_port=%d, remote_port=%d", pcb->local_port, pcb->remote_port); - ESP_LWIP_LOGI("flags=%x", pcb->flags); - ESP_LWIP_LOGI("pooltmr=%d pollinterval=%d, last_tmr=%d tmr=%d rtmer=%d", pcb->polltmr, pcb->pollinterval, pcb->last_timer, pcb->tmr, pcb->rtime); - ESP_LWIP_LOGI("recv_nxt=%d recv_wnd=%d recv_ann_wnd=%d recv_ann_right_edge=%d", pcb->rcv_nxt, pcb->rcv_wnd, pcb->rcv_ann_wnd, pcb->rcv_ann_right_edge); - ESP_LWIP_LOGI("mss=%d", pcb->mss); - ESP_LWIP_LOGI("rttest=%d rtseq=%d sa=%d sv=%d", pcb->rttest, pcb->rtseq, pcb->sa, pcb->sv); - ESP_LWIP_LOGI("rto=%d nrtx=%d", pcb->rto, pcb->nrtx); - ESP_LWIP_LOGI("dupacks=%d lastack=%d", pcb->dupacks, pcb->lastack); -#if ESP_PER_SOC_TCP_WND - ESP_LWIP_LOGI("per_soc_window=%d per_soc_snd_buf=%d", pcb->per_soc_tcp_wnd, pcb->per_soc_tcp_snd_buf); -#endif - ESP_LWIP_LOGI("cwnd=%d ssthreash=%d", pcb->cwnd, pcb->ssthresh); - ESP_LWIP_LOGI("snd_next=%d snd_wl1=%d snd_wl2=%d", pcb->snd_nxt, pcb->snd_wl1, pcb->snd_wl2); - ESP_LWIP_LOGI("snd_lbb=%d snd_wnd=%d snd_wnd_max=%d", pcb->snd_lbb, pcb->snd_wnd, pcb->snd_wnd_max); - //ESP_LWIP_LOGI("acked=%d", pcb->acked); - ESP_LWIP_LOGI("snd_buf=%d snd_queuelen=%d", pcb->snd_buf, pcb->snd_queuelen); - ESP_LWIP_LOGI("unsent_oversize=%d", pcb->unsent_oversize); - ESP_LWIP_LOGI("keep_idle=%d keep_intvl=%d keep_cnt=%d", pcb->keep_idle, pcb->keep_intvl, pcb->keep_cnt); - ESP_LWIP_LOGI("persist_cnt=%d persist_backoff=%d", pcb->persist_cnt, pcb->persist_backoff); - ESP_LWIP_LOGI("keep_cnt_sent=%d", pcb->keep_cnt_sent); - - ESP_LWIP_LOGI("unsent segments:"); - seg = pcb->unsent; - DBG_LWIP_SEG_SHOW(seg) - - ESP_LWIP_LOGI("unacked segments:"); - seg = pcb->unacked; - DBG_LWIP_SEG_SHOW(seg); - -#if TCP_QUEUE_OOSEQ - ESP_LWIP_LOGI("ooseq segments:"); - seg = pcb->ooseq; - DBG_LWIP_SEG_SHOW(seg); -#endif - - ESP_LWIP_LOGI("refused data=%p", pcb->refused_data); - -#if ESP_STATS_TCP - dbg_lwip_tcp_pcb_cnt_show(pcb); -#endif -} - -static void dbg_lwip_tcp_pcb_list_show(struct tcp_pcb* pcb) -{ - while(pcb){ - dbg_lwip_tcp_pcb_one_show(pcb); - pcb = pcb->next; - } -} +#define TAG "lwipd" +extern struct lwip_sock* lwip_socket_debug_get_socket(int fd); +extern void lwip_socket_debug_done_socket(struct lwip_sock *sock); extern struct tcp_pcb *tcp_bound_pcbs; extern struct tcp_pcb *tcp_active_pcbs; extern struct tcp_pcb *tcp_tw_pcbs; -void dbg_lwip_tcp_pcb_show(void) -{ - ESP_LWIP_LOGI("-------------active pcbs------------"); - dbg_lwip_tcp_pcb_list_show(tcp_active_pcbs); - ESP_LWIP_LOGI("-------------bound pcbs-------------"); - dbg_lwip_tcp_pcb_list_show(tcp_bound_pcbs); - ESP_LWIP_LOGI("-------------tw pcbs------------"); - dbg_lwip_tcp_pcb_list_show(tcp_tw_pcbs); -} - -void dbg_lwip_udp_pcb_one_show(struct udp_pcb *pcb) -{ - ESP_LWIP_LOGI("pcb=%p next=%p", pcb, (void*)pcb->next); - DBG_LWIP_IP_PCB_SHOW(pcb); - ESP_LWIP_LOGI("flags=%x", pcb->flags); - ESP_LWIP_LOGI("local_port=%d remote_port=%d", pcb->local_port, pcb->remote_port); - ESP_LWIP_LOGI("recv cb=%p recv_arg=%p", pcb->recv, pcb->recv_arg); -} - extern struct udp_pcb *udp_pcbs; -void dbg_lwip_udp_pcb_show(void) -{ - struct udp_pcb *pcb = udp_pcbs; - - while (pcb){ - dbg_lwip_udp_pcb_one_show(pcb); - pcb = pcb->next; - } -} - -void dbg_lwip_tcp_rxtx_show(void) -{ - ESP_LWIP_LOGI("TBC"); -} - -void dbg_lwip_udp_rxtx_show(void) -{ - ESP_LWIP_LOGI("TBC"); -} - -void dbg_lwip_stats_show(void) -{ - TCP_STATS_DISPLAY(); - UDP_STATS_DISPLAY(); - ICMP_STATS_DISPLAY(); - IGMP_STATS_DISPLAY(); - IP_STATS_DISPLAY(); - IPFRAG_STATS_DISPLAY(); - ETHARP_STATS_DISPLAY(); - LINK_STATS_DISPLAY(); - MEM_STATS_DISPLAY(); - SYS_STATS_DISPLAY(); - IP6_STATS_DISPLAY(); - ICMP6_STATS_DISPLAY(); - IP6_FRAG_STATS_DISPLAY(); - MLD6_STATS_DISPLAY(); - ND6_STATS_DISPLAY(); - ESP_STATS_DROP_DISPLAY(); -} - -#if (ESP_STATS_MEM == 1) - -uint32_t g_lwip_mem_cnt[MEMP_MAX][2]; -extern const struct memp_desc * const memp_pools[MEMP_MAX]; - -void dbg_lwip_cnt_show(void) -{ - int i=0; - - ESP_LWIP_LOGI("-----lwip memory counter-----"); - ESP_LWIP_LOGI("%6s %8s %8s", "index", "alloc", "free"); - for (i=0; ios_mbox) { + ESP_LOGI(TAG, "lwip mbox=%p msg=%u", mbox->os_mbox, uxQueueMessagesWaiting(mbox->os_mbox)); + } + + if (g_lwip_task) { + ESP_LOGI(TAG, "lwip task=%p state=%d", g_lwip_task, eTaskGetState(g_lwip_task)); + } + +} + +static uint32_t lwip_debug_pbuf_len(struct pbuf *buf) +{ + uint32_t cnt = 0; + + while (buf) { + cnt ++; + buf = buf->next; + } + + return cnt; +} + +static uint32_t lwip_debug_tcp_seg_len(struct tcp_seg *seg) +{ + uint32_t cnt = 0; + + while (seg) { + cnt ++; + seg = seg->next; + } + + return cnt; +} + +static int lwip_debug_deep_copy_tcp_pcb_list(struct tcp_pcb *pcb, lwip_debug_tcp_pcb_t **pdbgpcb) +{ + lwip_debug_tcp_pcb_t *dbgpcb = NULL; + lwip_debug_tcp_pcb_t *pre = NULL; + + while(pcb){ + dbgpcb = (lwip_debug_tcp_pcb_t*)mem_malloc(sizeof(lwip_debug_tcp_pcb_t)); + + if (!dbgpcb) { + ESP_LOGI(TAG, "Failed to allocate TCP PCB"); + return -1; + } + + memset(dbgpcb, 0, sizeof(lwip_debug_tcp_pcb_t)); + memcpy((void*)dbgpcb, (void*)pcb, sizeof(struct tcp_pcb)); + + dbgpcb->unsent_cnt = lwip_debug_tcp_seg_len(pcb->unsent); + dbgpcb->unack_cnt = lwip_debug_tcp_seg_len(pcb->unacked); + dbgpcb->oos_cnt = lwip_debug_tcp_seg_len(pcb->ooseq); + dbgpcb->refused_cnt = lwip_debug_pbuf_len(pcb->refused_data); + + if ( (*pdbgpcb) == NULL) { + *pdbgpcb = dbgpcb; + pre = dbgpcb; + } else { + pre->next = dbgpcb; + pre = pre->next; + } + pcb = pcb->next; + } + + return 0; +} + +static int lwip_debug_get_tcp_pcbs(lwip_debug_info_t *info) +{ + lwip_debug_deep_copy_tcp_pcb_list(tcp_active_pcbs, &info->active_pcbs); + lwip_debug_deep_copy_tcp_pcb_list(tcp_bound_pcbs, &info->bound_pcbs); + lwip_debug_deep_copy_tcp_pcb_list(tcp_tw_pcbs, &info->tw_pcbs); + return 0; +} + +static int lwip_debug_deep_copy_udp_pcb_list(struct udp_pcb *pcb, lwip_debug_udp_pcb_t **pdbgpcb) +{ + lwip_debug_udp_pcb_t *dbgpcb = NULL; + lwip_debug_udp_pcb_t *pre = NULL; + + while (pcb) { + dbgpcb = (lwip_debug_udp_pcb_t*)mem_malloc(sizeof(lwip_debug_udp_pcb_t)); + + if (!dbgpcb) { + ESP_LOGI(TAG, "Failed to allocate UDP PCB"); + return -1; + } + + memset(dbgpcb, 0, sizeof(lwip_debug_udp_pcb_t)); + memcpy((void*)dbgpcb, (void*)pcb, sizeof(struct udp_pcb)); + + if ( (*pdbgpcb) == NULL) { + *pdbgpcb = dbgpcb; + pre = dbgpcb; + } else { + pre->next = dbgpcb; + pre = pre->next; + } + + pcb = pcb->next; + } + + return 0; +} + +static int lwip_debug_get_udp_pcbs(lwip_debug_info_t *info) +{ + lwip_debug_deep_copy_udp_pcb_list(udp_pcbs, &info->udp_pcbs); + return 0; +} + +static void lwip_socket_debug_free_sockets(lwip_debug_sock_t *dbgsock) +{ + struct lwip_sock *sock = NULL; + int i=0; + + for (i=0; iconn) { + if (sock->conn->pcb.tcp) { + free(sock->conn->pcb.tcp); + } + free(sock->conn); + } + } + + free(dbgsock); +} + +int lwip_socket_debug_deep_copy_socket(struct lwip_sock *sock, lwip_debug_sock_t *dbgsock) +{ + struct lwip_sock *dbgsock_base = (struct lwip_sock*)dbgsock; + struct tcp_pcb *tcp_pcb_copy = NULL; + struct udp_pcb *udp_pcb_copy = NULL; + struct netconn *conn_copy = NULL; + struct netconn *conn = NULL; + + conn = sock->conn; + if (!conn) { + return 0; + } + + conn_copy = (struct netconn*)mem_malloc(sizeof(struct netconn)); + if (!conn_copy) { + return -1; + } + + memcpy(conn_copy, conn, sizeof(struct netconn)); + dbgsock_base->conn = conn_copy; + conn_copy->pcb.tcp = NULL; + + if (conn->recvmbox && conn->recvmbox->os_mbox) { + dbgsock->recvmbox_cnt = uxQueueMessagesWaiting(conn->recvmbox->os_mbox); + } + +#if LWIP_TCP + if (conn->acceptmbox && conn->acceptmbox->os_mbox) { + dbgsock->acceptmbox_cnt = uxQueueMessagesWaiting(conn->acceptmbox->os_mbox); + } +#endif + + if (conn->pcb.tcp) { + switch (conn->type) { + case NETCONN_TCP: + tcp_pcb_copy = (struct tcp_pcb*) mem_malloc(sizeof(struct tcp_pcb)); + if (!tcp_pcb_copy) { + goto _exit; + } + + memcpy(tcp_pcb_copy, conn->pcb.tcp, sizeof(struct tcp_pcb)); + conn_copy->pcb.tcp = tcp_pcb_copy; + break; + + case NETCONN_UDP: + udp_pcb_copy = (struct udp_pcb*) mem_malloc(sizeof(struct udp_pcb)); + if (!udp_pcb_copy) { + goto _exit; + } + + memcpy(udp_pcb_copy, sock->conn->pcb.udp, sizeof(struct udp_pcb)); + conn_copy->pcb.udp = udp_pcb_copy; + break; + + default: + break; + } + } + + return 0; + +_exit: + if (tcp_pcb_copy) { + free(tcp_pcb_copy); + } + + if (udp_pcb_copy) { + free(udp_pcb_copy); + } + + if (conn_copy) { + free(conn_copy); + } + + dbgsock_base->conn = NULL; + return -1; +} + +static int lwip_socket_debug_get_all_sockets(void **arg) +{ + lwip_debug_sock_t **pdbgsocks = (lwip_debug_sock_t**)arg; + lwip_debug_sock_t *dbgsock = NULL; + struct lwip_sock *sock; + int i; + + if (!pdbgsocks) { + return -1; + } + + *pdbgsocks = NULL; + dbgsock = (lwip_debug_sock_t*) mem_malloc(sizeof(lwip_debug_sock_t) * NUM_SOCKETS); + if (!dbgsock) { + return -1; + } + + memset(dbgsock, 0, sizeof(lwip_debug_sock_t) * NUM_SOCKETS); + *pdbgsocks = dbgsock; + + for (i=0; i socket list"); + + if (!sockets) { + return; + } + + for (i=0; iconn; + recv_bufsize = recv_avail = send_timeout = recv_timeout = linger = 0; + if (conn) { +#if LWIP_SO_SNDTIMEO + send_timeout = conn->send_timeout; +#endif + +#if LWIP_SO_RCVTIMEO + recv_timeout = conn->recv_timeout; +#endif + +#if LWIP_SO_LINGER + linger = conn->linger; +#endif + +#if LWIP_SO_RCVBUF + recv_bufsize = conn->recv_bufsize; + recv_avail = conn->recv_avail; +#endif + + if (conn->type == NETCONN_TCP) { + local_ip = &conn->pcb.tcp->local_ip; + remote_ip = &conn->pcb.tcp->remote_ip; + local_port = conn->pcb.tcp->local_port; + remote_port = conn->pcb.tcp->remote_port; + } else if (conn->type == NETCONN_UDP) { + local_ip = &conn->pcb.tcp->local_ip; + remote_ip = &conn->pcb.tcp->remote_ip; + local_port = conn->pcb.tcp->local_port; + remote_port = conn->pcb.tcp->remote_port; + } else { + local_ip = remote_ip = &empty_ip; + local_port = remote_port = 0; + } + + ESP_LOGI(TAG, "%2x %2x %8x:%4x %8x:%4x %3x %3x %3x %2x %2x %2x %4x %3x %4x %2x %4x %4x %4x %3x %3x %5x %3x %3x", + i+LWIP_SOCKET_OFFSET, local_ip->type, local_ip->u_addr.ip4.addr, local_port, remote_ip->u_addr.ip4.addr, remote_port, + sock->rcvevent, sock->sendevent, sock->errevent, sock->select_waiting, sock->state, sock->ref, + conn->type, conn->state, conn->last_err, 0, send_timeout, recv_timeout, recv_bufsize, + recv_avail, linger, conn->flags, sockets[i].recvmbox_cnt, sockets[i].acceptmbox_cnt); + } else { + ESP_LOGI(TAG, "%2x %21s %21s %3x %3x %3x %2x %2x %2x %4s %3s %4s %2s %4s %4s %4s %3s %3s %5s %3s %3s", + i+LWIP_SOCKET_OFFSET, "-:-", "-:-", sock->rcvevent, sock->sendevent, sock->errevent, sock->select_waiting, sock->state, sock->ref, + "-", "-", "-", "-", "-", "-", "-", + "-", "-", "-", "-", "-"); + } + } +} + +static void lwip_debug_dump_tcp_pcb_list_part1(lwip_debug_tcp_pcb_t* dbgpcb, uint32_t type, uint32_t *id) +{ + char t[] = {'A', 'B', 'T'}; + struct tcp_pcb *pcb; + uint8_t i = *id; + + while(dbgpcb){ + pcb = (struct tcp_pcb *)&dbgpcb->pcb; + ESP_LOGI(TAG, "%2d %c %2x %8x:%4x %8x:%4x %2x %2x %5x %5x %6x %5x %5x %4x %4s %4s %4s %4s %4s", + i++, t[type], pcb->local_ip.type, pcb->local_ip.u_addr.ip4.addr, pcb->local_port, pcb->remote_ip.u_addr.ip4.addr, pcb->remote_port, pcb->state, pcb->prio, + pcb->flags, pcb->polltmr, pcb->pollinterval, pcb->last_timer, pcb->tmr, pcb->mss, pcb->sent?"x":"0", pcb->recv?"x":"0", pcb->connected?"x":"0", + pcb->poll?"x":"0", pcb->errf?"x":"0"); + dbgpcb = dbgpcb->next; + } + *id = *id + i; +} + +static void lwip_debug_dump_tcp_pcb_list_part2(lwip_debug_tcp_pcb_t* dbgpcb, uint32_t type, uint32_t *id) +{ + struct tcp_pcb *pcb; + uint8_t i = *id; + + while(dbgpcb){ + pcb = (struct tcp_pcb *)&dbgpcb->pcb; + ESP_LOGI(TAG, "%2x %8x %8x %8x %8x %8x %3x %6x", + i++, pcb->rcv_nxt, pcb->rcv_wnd, pcb->rcv_ann_wnd, pcb->rcv_ann_right_edge, 0, dbgpcb->oos_cnt, dbgpcb->refused_cnt); + dbgpcb = dbgpcb->next; + } + *id = *id + i; +} + +static void lwip_debug_dump_tcp_pcb_list_part3(lwip_debug_tcp_pcb_t* dbgpcb, uint32_t type, uint32_t *id) +{ + struct tcp_pcb *pcb; + uint8_t i = *id; + + while(dbgpcb){ + pcb = (struct tcp_pcb *)&dbgpcb->pcb; + + ESP_LOGI(TAG, "%2x %6x %8x %4x %4x %4x %4x %8x %4x %8x %8x %8x %4x %4x %4x", + i++, pcb->rttest, pcb->rtseq, pcb->sa, pcb->sv, pcb->rto, pcb->nrtx, pcb->dupacks, pcb->lastack, pcb->cwnd, + pcb->ssthresh, 0, pcb->persist_cnt, pcb->persist_backoff, 0); + + dbgpcb = dbgpcb->next; + } + *id = *id + i; +} + +static void lwip_debug_dump_tcp_pcb_list_part4(lwip_debug_tcp_pcb_t* dbgpcb, uint32_t type, uint32_t *id) +{ + uint32_t unsent_oversize = 0; + struct tcp_pcb *pcb; + uint8_t i = *id; + + while(dbgpcb){ + pcb = (struct tcp_pcb *)&dbgpcb->pcb; + +#if TCP_OVERSIZE + unsent_oversize = pcb->unsent_oversize; +#endif + + ESP_LOGI(TAG, "%2x %8x %8x %8x %8x %8x %4x %5x %5x %6x %3x %3x", + i++, pcb->snd_nxt, pcb->snd_wl1, pcb->snd_wl2, pcb->snd_lbb, pcb->snd_wnd, pcb->snd_wnd_max, pcb->snd_buf, + pcb->snd_queuelen, unsent_oversize, dbgpcb->unsent_cnt, dbgpcb->unack_cnt); + dbgpcb = dbgpcb->next; + } + *id = *id + i; +} + + + +static void lwip_debug_dump_tcp_pcbs_part1(lwip_debug_info_t *info) +{ + uint32_t id = 0; + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%2s %1s %2s %13s %13s %2s %2s %5s %5s %6s %5s %5s %4s %4s %4s %4s %4s %4s", + "id", "t", "46", "src ip:port", "dst ip:port", "st", "pr", "flags", "p_tmr", "p_itvl", + "l_tmr", "tmr", "mss", "sent", "recv", "conn", "poll", "errf"); + lwip_debug_dump_tcp_pcb_list_part1(info->active_pcbs, 0, &id); + lwip_debug_dump_tcp_pcb_list_part1(info->bound_pcbs, 1, &id); + lwip_debug_dump_tcp_pcb_list_part1(info->tw_pcbs, 2, &id); +} + +static void lwip_debug_dump_tcp_pcbs_part2(lwip_debug_info_t *info) +{ + uint32_t id = 0; + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%2s %8s %8s %8s %8s %8s %3s %6s", "id", "r_next", "r_wnd", "r_a_wnd", "r_a_r_e", "b_acked", "oos", "refuse"); + lwip_debug_dump_tcp_pcb_list_part2(info->active_pcbs, 0, &id); + lwip_debug_dump_tcp_pcb_list_part2(info->bound_pcbs, 1, &id); + lwip_debug_dump_tcp_pcb_list_part2(info->tw_pcbs, 2, &id); +} + +static void lwip_debug_dump_tcp_pcbs_part3(lwip_debug_info_t *info) +{ + uint32_t id = 0; + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%2s %6s %8s %4s %4s %4s %4s %8s %4s %8s %8s %8s %4s %4s %4s", + "id", "rttest", "rtseq", "sa", "sv", "rto", "nrtx", "dup", "last", "cwnd", "ssthresh", "rto_end", "pist", "p_bo", "p_p"); + + lwip_debug_dump_tcp_pcb_list_part3(info->active_pcbs, 0, &id); + lwip_debug_dump_tcp_pcb_list_part3(info->bound_pcbs, 1, &id); + lwip_debug_dump_tcp_pcb_list_part3(info->tw_pcbs, 2, &id); +} + +static void lwip_debug_dump_tcp_pcbs_part4(lwip_debug_info_t *info) +{ + uint32_t id = 0; + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "%2s %8s %8s %8s %8s %8s %4s %5s %5s %6s %3s %3s", + "id", "snd_next", "snd_wl1", "snd_wl2", "wnd_lbb", "s_wnd", "s_wm", "s_buf", "s_qlen", "uns_os", "uns", "una"); + + lwip_debug_dump_tcp_pcb_list_part4(info->active_pcbs, 0, &id); + lwip_debug_dump_tcp_pcb_list_part4(info->bound_pcbs, 1, &id); + lwip_debug_dump_tcp_pcb_list_part4(info->tw_pcbs, 2, &id); +} + +static void lwip_debug_dump_tcp_pcbs(lwip_debug_info_t *info) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========> tcp pcb list"); + + if ( !(info->active_pcbs) && !(info->bound_pcbs) && !(info->tw_pcbs) ) { + return; + } + + lwip_debug_dump_tcp_pcbs_part1(info); + lwip_debug_dump_tcp_pcbs_part3(info); + lwip_debug_dump_tcp_pcbs_part4(info); + lwip_debug_dump_tcp_pcbs_part2(info); +} + +static void lwip_debug_dump_udp_pcbs(lwip_debug_info_t *info) +{ + lwip_debug_udp_pcb_t *dbgpcb = info->udp_pcbs; + struct udp_pcb *pcb; + uint32_t i = 0; + uint32_t mcast_ip = 0; + uint8_t mcast_ttl = 0; + + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========> udp pcb list"); + + if ( !dbgpcb ) { + return; + } + + ESP_LOGI(TAG, "%2s %2s %13s %13s %5s %4s %4s %5s %4s %3s", + "id", "46", "src ip:port", "dst ip:port", "flags", "m_ip", "m_if", "m_ttl", "recv", "arg"); + while (dbgpcb) { + pcb = (struct udp_pcb *)dbgpcb; + +#if LWIP_MULTICAST_TX_OPTIONS + mcast_ip = pcb->multicast_ip.u_addr.ip4.addr; + mcast_ttl = pcb->mcast_ttl; +#endif + + ESP_LOGI(TAG, "%2x %2x %8x:%4x %8x:%4x %5x %4x %4x %5x %4s %3s", + i++, pcb->local_ip.type, pcb->local_ip.u_addr.ip4.addr, pcb->local_port, pcb->remote_ip.u_addr.ip4.addr, pcb->remote_port, + pcb->flags, mcast_ip, mcast_ttl, pcb->mcast_ttl, pcb->recv?"x":"0", pcb->recv_arg?"x":"0"); + dbgpcb = dbgpcb->next; + } +} + +static void lwip_debug_dump_sockets(lwip_debug_info_t *info) +{ + lwip_debug_dump_open_sockets(info->sockets); + lwip_debug_dump_tcp_pcbs(info); + lwip_debug_dump_udp_pcbs(info); +} + +static void lwip_debug_api_cb(void *api_msg) +{ + lwip_debug_api_msg_t *msg = (lwip_debug_api_msg_t *)api_msg; + + if (!msg || !msg->api_fn) { + return; + } + + msg->ret = msg->api_fn(msg); + sys_sem_signal(&s_lwip_debug_api_sem); + return; +} + +static int lwip_debug_api_call(lwip_debug_api_msg_t *msg) +{ + int ret; + + if (!msg || (!msg->api_fn)) { + ESP_LOGI(TAG, "null msg/fn"); + return ESP_ERR_INVALID_ARG; + } + + msg->ret = ESP_FAIL; + + if (!s_lwip_debug_api_sem) { + ret = sys_sem_new(&s_lwip_debug_api_sem, 1); + if (ESP_OK != ret) { + ESP_LOGI(TAG, "failed to create lwip sync sem"); + return ESP_ERR_NO_MEM; + } + } + + sys_arch_sem_wait(&s_lwip_debug_api_sem, 0); + tcpip_send_msg_wait_sem((tcpip_callback_fn)lwip_debug_api_cb, msg, &s_lwip_debug_api_sem); + sys_sem_signal(&s_lwip_debug_api_sem); + + return msg->ret; +} + +int lwip_debug_get_sockets_local(lwip_debug_api_msg_t *msg) +{ + lwip_debug_info_t *info = (lwip_debug_info_t*) msg->arg; + + if (0 != lwip_socket_debug_get_all_sockets(&info->sockets)) { + return -1; + } + + if (0 != lwip_debug_get_tcp_pcbs(info)) { + return -1; + } + + if (0 != lwip_debug_get_udp_pcbs(info)) { + return -1; + } + + return 0; +} + +static int lwip_debug_get_sockets(lwip_debug_info_t *info) +{ + lwip_debug_api_msg_t msg; + + msg.api_fn = lwip_debug_get_sockets_local; + msg.arg = (void*)info; + msg.ret = ESP_FAIL; + + lwip_debug_api_call(&msg); + return msg.ret; +} + +static void lwip_debug_free_tcp_pcb_list(lwip_debug_tcp_pcb_t *pcb) +{ + lwip_debug_tcp_pcb_t *tmp; + + while (pcb) { + tmp = pcb; + pcb = pcb->next; + free(tmp); + } +} + +static void lwip_debug_free_tcp_pcbs(lwip_debug_info_t *info) +{ + if (!info) { + return; + } + + if (info->active_pcbs) { + lwip_debug_free_tcp_pcb_list(info->active_pcbs); + info->active_pcbs = 0; + } + + + if (info->bound_pcbs) { + lwip_debug_free_tcp_pcb_list(info->bound_pcbs); + info->bound_pcbs = 0; + } + + if (info->tw_pcbs) { + lwip_debug_free_tcp_pcb_list(info->tw_pcbs); + info->tw_pcbs = 0; + } +} + +static void lwip_debug_free_udp_pcb_list(lwip_debug_udp_pcb_t *pcb) +{ + lwip_debug_udp_pcb_t *tmp; + + while (pcb) { + tmp = pcb; + pcb = pcb->next; + free(tmp); + } +} + +static void lwip_debug_free_udp_pcbs(lwip_debug_info_t *info) +{ + if (!info) { + return; + } + + if (info->udp_pcbs) { + lwip_debug_free_udp_pcb_list(info->udp_pcbs); + } +} + +static void lwip_debug_free_sockets(lwip_debug_info_t *info) +{ + if (!info) { + return; + } + + if (info->sockets) { + lwip_socket_debug_free_sockets(info->sockets); + info->sockets = NULL; + } + + lwip_debug_free_tcp_pcbs(info); + lwip_debug_free_udp_pcbs(info); +} + +#if LWIP_STATS +static void lwip_debug_dump_igmp_statistics(struct stats_igmp *proto, const char *name) +{ + ESP_LOGI(TAG, "%8s %8x %8x %4x %4x %4x %4x %4x %5x %5x %5x %5x %5x %5x %5x", + name, proto->xmit, proto->recv, proto->drop, proto->chkerr, proto->lenerr, + proto->memerr, proto->proterr, proto->rx_v1, proto->rx_group, proto->rx_general, + proto->rx_report, proto->tx_join, proto->tx_leave, proto->tx_report); +} + + +static void lwip_debug_dump_multicast_statistics(void) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========> LWIP multicast statistics"); + ESP_LOGI(TAG, "%8s %8s %8s %4s %4s %4s %4s %4s %5s %5s %5s %5s %5s %5s %5s", + "name", "xmit", "recv", "drop", "chk", "len", "mem", "prot", "rxv1", "rx_gr", "rx_gl", "rx_rp", "tx_jn", "tx_lv", "tx_rp"); + +#if IGMP_STATS + lwip_debug_dump_igmp_statistics(&lwip_stats.igmp, "IGMP"); +#endif + +#if MLD6_STATS + lwip_debug_dump_igmp_statistics(&lwip_stats.mld6, "MLDv1"); +#endif +} + +static void lwip_debug_dump_protocol_statistics(struct stats_proto *proto, const char *name) +{ + ESP_LOGI(TAG, "%8s %8x %8x %8x %4x %4x %4x %4x %4x %4x %4x %4x %8x", + name, proto->xmit, proto->recv, proto->fw, proto->drop, proto->chkerr, proto->lenerr, + proto->memerr, proto->rterr, proto->proterr, proto->opterr, proto->err, proto->cachehit); +} + +static void lwip_debug_dump_unicast_statistics(void) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========> LWIP counters"); + ESP_LOGI(TAG, "%8s %8s %8s %8s %4s %4s %4s %4s %4s %4s %4s %4s %8s", + "name", "xmit", "recv", "forward", "drop", "chk", "len", "mem", "rt", "prot", "opt", "err", "hit"); +#if TCP_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.tcp, "TCP"); +#endif +#if UDP_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.udp, "UDP"); +#endif +#if ICMP_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.icmp, "ICMP"); +#endif +#if IP_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.ip, "IP"); +#endif +#if IPFRAG_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.ip_frag, "IPFRAG"); +#endif +#if ETHARP_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.etharp, "ETHARP"); +#endif +#if LINK_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.link, "LINK"); +#endif +#if IP6_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.ip6, "IPV6"); +#endif +#if ICMP6_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.icmp6, "ICMP6"); +#endif +#if IP6_FRAG_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.ip6_frag, "IPV6FRAG"); +#endif +#if ND6_FRAG_STATS + lwip_debug_dump_protocol_statistics(&lwip_stats.nd6, "ND"); +#endif + +} +#endif + +void esp_lwip_debug_dump_sockets(void) +{ + lwip_debug_info_t info; + + memset(&info, 0, sizeof(info)); + + if (ESP_OK == lwip_debug_get_sockets(&info)) { + lwip_debug_dump_sockets(&info); + lwip_debug_free_sockets(&info); + } +} + +static void lwip_debug_dump_sys_statistics(void) +{ + ESP_LOGI(TAG, ""); + ESP_LOGI(TAG, "========> LWIP system counters"); + ESP_LOGI(TAG, "%8s %8s %8s", "tpost_f", "fetch_f", "tfetch_f"); + ESP_LOGI(TAG, "%8x %8x %8x", g_esp_lwip_stats.trypost_fail, g_esp_lwip_stats.fetch_fail, g_esp_lwip_stats.tryfetch_fail); +} + +void esp_lwip_debug_dump_stats(void) +{ +#if LWIP_STATS + lwip_debug_dump_sys_statistics(); + lwip_debug_dump_unicast_statistics(); + lwip_debug_dump_multicast_statistics(); +#endif + + //TODO + // 1. mbox post fail/recv timeout + // 2. tcpip mbox counter + // 3. tcp abort + // 4. ARP drop + // 5. DHCP drop + // 6. DNS fail + // 7. DHCP renew time, renew fail time, rebind timer + // 8. +} + +void esp_lwip_dump(uint64_t modules) +{ + if (modules & LWIP_MODULE_SOCKETS) { + esp_lwip_debug_dump_sockets(); + } + + if (modules & LWIP_MODULE_STATS) { + esp_lwip_debug_dump_stats(); + } +} + diff --git a/components/lwip/port/esp32/freertos/sys_arch.c b/components/lwip/port/esp32/freertos/sys_arch.c index 1168b9e89e..558698d04d 100644 --- a/components/lwip/port/esp32/freertos/sys_arch.c +++ b/components/lwip/port/esp32/freertos/sys_arch.c @@ -40,6 +40,7 @@ #include "arch/sys_arch.h" #include "lwip/stats.h" #include "esp_log.h" +#include "debug/lwip_debug.h" /* This is the number of threads that can be started with sys_thread_new() */ #define SYS_THREAD_MAX 4 @@ -249,6 +250,7 @@ sys_mbox_trypost(sys_mbox_t *mbox, void *msg) } else { LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("trypost mbox=%p fail\n", (*mbox)->os_mbox)); xReturn = ERR_MEM; + SYS_ARCH_INC_WITH_LOCK(trypost_fail); } return xReturn; @@ -304,6 +306,7 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) ulReturn = Elapsed; } else { // timed out blocking for message + SYS_ARCH_INC_WITH_LOCK(fetch_fail); ulReturn = SYS_ARCH_TIMEOUT; } @@ -325,6 +328,7 @@ sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) ulReturn = ERR_OK; } else { ulReturn = SYS_MBOX_EMPTY; + SYS_ARCH_INC_WITH_LOCK(tryfetch_fail); } return ulReturn; diff --git a/components/lwip/port/esp32/include/debug/lwip_debug.h b/components/lwip/port/esp32/include/debug/lwip_debug.h index 4da520269a..2a16958694 100644 --- a/components/lwip/port/esp32/include/debug/lwip_debug.h +++ b/components/lwip/port/esp32/include/debug/lwip_debug.h @@ -16,10 +16,25 @@ #ifndef _LWIP_DEBUG_H #define _LWIP_DEBUG_H -void dbg_lwip_tcp_pcb_show(void); -void dbg_lwip_udp_pcb_show(void); -void dbg_lwip_tcp_rxtx_show(void); -void dbg_lwip_udp_rxtx_show(void); -void dbg_lwip_mem_cnt_show(void); +#include "esp_log.h" + +typedef struct { + uint32_t trypost_fail; + uint32_t fetch_fail; + uint32_t tryfetch_fail; +} esp_lwip_stats_t; + +extern esp_lwip_stats_t g_esp_lwip_stats; + +#define SYS_ARCH_INC_WITH_LOCK(_f) do {\ + sys_arch_protect();\ + g_esp_lwip_stats._f ++;\ + sys_arch_unprotect(0);\ +}while(0) + +#define LWIP_MODULE_SOCKETS 1 +#define LWIP_MODULE_STATS (1<<1) + +void esp_lwip_dump(uint64_t modules); #endif