From ad9787bb4d88378c71b84c44a65a1be7930fa504 Mon Sep 17 00:00:00 2001 From: Abhik Roy Date: Sat, 6 Apr 2024 01:18:06 +1100 Subject: [PATCH] feat(esp_netif): Allow traffic reporting runtime enable/disable --- components/esp_netif/Kconfig | 6 +- components/esp_netif/include/esp_netif.h | 33 ++++++++- .../esp_netif/include/esp_netif_types.h | 21 +++--- components/esp_netif/lwip/esp_netif_lwip.c | 70 ++++++++++++++++--- .../esp_netif/lwip/esp_netif_lwip_internal.h | 3 + docs/en/api-reference/network/esp_netif.rst | 52 ++++++++++++++ 6 files changed, 160 insertions(+), 25 deletions(-) diff --git a/components/esp_netif/Kconfig b/components/esp_netif/Kconfig index fed9bd3176..4511bbeaaf 100644 --- a/components/esp_netif/Kconfig +++ b/components/esp_netif/Kconfig @@ -9,7 +9,7 @@ menu "ESP NETIF Adapter" The IP address may be lost because of some reasons, e.g. when the station disconnects from soft-AP, or when DHCP IP renew fails etc. If the IP lost timer is enabled, it will - be started everytime the IP is lost. Event SYSTEM_EVENT_STA_LOST_IP will be raised if + be started every time the IP is lost. Event SYSTEM_EVENT_STA_LOST_IP will be raised if the timer expires. The IP lost timer is stopped if the station get the IP again before the timer expires. @@ -38,7 +38,7 @@ menu "ESP NETIF Adapter" config ESP_NETIF_REPORT_DATA_TRAFFIC bool "Report data traffic via events" - default n + default y help Enable if esp_netif_transmit() and esp_netif_receive() should generate events. This can be useful to blink data traffic indication lights. @@ -83,5 +83,5 @@ menu "ESP NETIF Adapter" default n help Enable LwIP IEEE 802.1D bridge support in ESP-NETIF. Note that "Number of clients store data in netif" - (LWIP_NUM_NETIF_CLIENT_DATA) option needs to be properly configured to be LwIP bridge avaiable! + (LWIP_NUM_NETIF_CLIENT_DATA) option needs to be properly configured to be LwIP bridge available! endmenu diff --git a/components/esp_netif/include/esp_netif.h b/components/esp_netif/include/esp_netif.h index 6dd6601509..7b2dc3fbd8 100644 --- a/components/esp_netif/include/esp_netif.h +++ b/components/esp_netif/include/esp_netif.h @@ -112,7 +112,7 @@ esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle dri * to TCP/IP stack. Similarly esp_netif_transmit is called from the TCP/IP stack whenever * a packet ought to output to the communication media. * - * @note These IO functions are registerd (installed) automatically for default interfaces + * @note These IO functions are registered (installed) automatically for default interfaces * (interfaces with the keys such as WIFI_STA_DEF, WIFI_AP_DEF, ETH_DEF). Custom interface * has to register these IO functions when creating interface using @ref esp_netif_new * @@ -138,6 +138,33 @@ esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle dri */ esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb); +/** + * @brief Enables transmit/receive event reporting for a network interface. + * + * These functions enables transmit and receive events reporting for a given esp-netif instance. + * Event reporting can be used to track data transfer activity and trigger application-specific actions. + * + * @param[in] esp_netif Handle to esp-netif instance + * + * @return + * - ESP_OK: Successfully enabled event reporting + * - ESP_FAIL: Event reporting not configured + */ +esp_err_t esp_netif_tx_rx_event_enable(esp_netif_t *esp_netif); + +/** + * @brief Disables transmit/receive event reporting for a network interface. + * + * These functions disables transmit and receive events reporting for a given esp-netif instance. + * + * @param[in] esp_netif Handle to esp-netif instance + * + * @return + * - ESP_OK: Successfully disabled event reporting + * - ESP_FAIL: Event reporting not configured + */ +esp_err_t esp_netif_tx_rx_event_disable(esp_netif_t *esp_netif); + /** * @} */ @@ -898,7 +925,7 @@ esp_err_t esp_netif_str_to_ip4(const char *src, esp_ip4_addr_t *dst); /** * @brief Converts Ascii internet IPv6 address into esp_ip4_addr_t - * Zeros in the IP address can be stripped or completely ommited: "2001:db8:85a3:0:0:0:2:1" or "2001:db8::2:1") + * Zeros in the IP address can be stripped or completely omitted: "2001:db8:85a3:0:0:0:2:1" or "2001:db8::2:1") * * @param[in] src IPv6 address in ascii representation (e.g. ""2001:0db8:85a3:0000:0000:0000:0002:0001") * @param[out] dst Address of the target esp_ip6_addr_t structure to receive converted address @@ -972,7 +999,7 @@ const char *esp_netif_get_desc(esp_netif_t *esp_netif); * * @param[in] esp_netif Handle to esp-netif instance * - * @return Integer representing the instance's route-prio, or -1 if invalid paramters + * @return Integer representing the instance's route-prio, or -1 if invalid parameters */ int esp_netif_get_route_prio(esp_netif_t *esp_netif); diff --git a/components/esp_netif/include/esp_netif_types.h b/components/esp_netif/include/esp_netif_types.h index 14bd3b0208..c7bc05f4ac 100644 --- a/components/esp_netif/include/esp_netif_types.h +++ b/components/esp_netif/include/esp_netif_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,7 +37,7 @@ extern "C" { /** - * @brief Definition of ESP-NETIF bridge controll + * @brief Definition of ESP-NETIF bridge control */ #define ESP_NETIF_BR_FLOOD -1 #define ESP_NETIF_BR_DROP 0 @@ -101,10 +101,7 @@ typedef enum { IP_EVENT_ETH_LOST_IP, /*!< ethernet lost IP and the IP is reset to 0 */ IP_EVENT_PPP_GOT_IP, /*!< PPP interface got IP */ IP_EVENT_PPP_LOST_IP, /*!< PPP interface lost IP */ -#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC - IP_EVENT_TRANSMIT, /*!< transmitting data */ - IP_EVENT_RECEIVE, /*!< receiving data */ -#endif + IP_EVENT_TX_RX, /*!< transmitting/receiving data packet */ } ip_event_t; /** @brief IP event base declaration */ @@ -131,7 +128,7 @@ typedef struct { */ typedef struct { esp_netif_t *esp_netif; /*!< Pointer to corresponding esp-netif object */ - esp_netif_ip_info_t ip_info; /*!< IP address, netmask, gatway IP address */ + esp_netif_ip_info_t ip_info; /*!< IP address, netmask, gateway IP address */ bool ip_changed; /*!< Whether the assigned IP has changed or not */ } ip_event_got_ip_t; @@ -155,12 +152,18 @@ typedef struct { uint8_t mac[6]; /*!< MAC address of the connected client */ } ip_event_ap_staipassigned_t; +typedef enum { + ESP_NETIF_TX = 0, // Data is being transmitted. + ESP_NETIF_RX = 1, // Data is being received. +} esp_netif_tx_rx_direction_t; + #ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC /** Event structure for IP_EVENT_TRANSMIT and IP_EVENT_RECEIVE */ typedef struct { esp_netif_t *esp_netif; /*!< Pointer to the associated netif handle */ - size_t len; /*!< Length of the data */ -} ip_event_transmit_receive_t; + size_t len; /*!< Length of the data */ + esp_netif_tx_rx_direction_t dir; /*!< Directions for data transfer >*/ +} ip_event_tx_rx_t; #endif typedef enum esp_netif_flags { diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index defe350635..a06106048e 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -1240,31 +1240,81 @@ void esp_netif_free_rx_buffer(void *h, void* buffer) esp_netif->driver_free_rx_buffer(esp_netif->driver_handle, buffer); } +#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC +static esp_err_t esp_netif_tx_rx_event_api(esp_netif_api_msg_t *msg) +{ + bool enable = (bool)msg->data; + esp_netif_t *esp_netif = msg->esp_netif; + if (esp_netif == NULL) { + ESP_LOGE(TAG, "Invalid esp_netif"); + } + + ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif); + esp_netif->tx_rx_events_enabled = enable; + + return ESP_OK; +} +#endif + +esp_err_t esp_netif_tx_rx_event_enable(esp_netif_t *esp_netif) +{ +#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC + return esp_netif_lwip_ipc_call(esp_netif_tx_rx_event_api, esp_netif, (void*)true /* Enable */); +#else + return ESP_FAIL; +#endif +} + +esp_err_t esp_netif_tx_rx_event_disable(esp_netif_t *esp_netif) +{ +#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC + return esp_netif_lwip_ipc_call(esp_netif_tx_rx_event_api, esp_netif, (void*)false /* Disable */); +#else + return ESP_FAIL; +#endif +} + esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len) { #ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC - ip_event_transmit_receive_t evt = { - .esp_netif = esp_netif, - .len = len, - }; - esp_event_post(IP_EVENT, IP_EVENT_TRANSMIT, &evt, sizeof(evt), 0); + if (unlikely(esp_netif->tx_rx_events_enabled)) { + ip_event_tx_rx_t evt = { + .esp_netif = esp_netif, + .len = len, + .dir = ESP_NETIF_TX, + }; + esp_event_post(IP_EVENT, IP_EVENT_TX_RX, &evt, sizeof(evt), 0); + } #endif return (esp_netif->driver_transmit)(esp_netif->driver_handle, data, len); } esp_err_t esp_netif_transmit_wrap(esp_netif_t *esp_netif, void *data, size_t len, void *pbuf) { +#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC + if (unlikely(esp_netif->tx_rx_events_enabled)) { + ip_event_tx_rx_t evt = { + .esp_netif = esp_netif, + .len = len, + .dir = ESP_NETIF_TX, + }; + esp_event_post(IP_EVENT, IP_EVENT_TX_RX, &evt, sizeof(evt), 0); + } +#endif return (esp_netif->driver_transmit_wrap)(esp_netif->driver_handle, data, len, pbuf); } esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb) { #ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC - ip_event_transmit_receive_t evt = { - .esp_netif = esp_netif, - .len = len, - }; - esp_event_post(IP_EVENT, IP_EVENT_RECEIVE, &evt, sizeof(evt), 0); + if (unlikely(esp_netif->tx_rx_events_enabled)) { + ip_event_tx_rx_t evt = { + .esp_netif = esp_netif, + .len = len, + .dir = ESP_NETIF_RX, + }; + esp_event_post(IP_EVENT, IP_EVENT_TX_RX, &evt, sizeof(evt), 0); + } #endif #ifdef CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS return esp_netif->lwip_input_fn(esp_netif->netif_handle, buffer, len, eb); diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index f1fc1f8bf8..c36ce179b4 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -98,6 +98,9 @@ struct esp_netif_obj { // event translation ip_event_t get_ip_event; ip_event_t lost_ip_event; +#ifdef CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC + bool tx_rx_events_enabled; +#endif // misc flags, types, keys, priority esp_netif_flags_t flags; diff --git a/docs/en/api-reference/network/esp_netif.rst b/docs/en/api-reference/network/esp_netif.rst index d1fff7e542..fe6c4c4d46 100644 --- a/docs/en/api-reference/network/esp_netif.rst +++ b/docs/en/api-reference/network/esp_netif.rst @@ -373,6 +373,58 @@ For more specific cases, please consult this guide: :doc:`/api-reference/network * When using Wi-Fi in ``AP+STA`` mode, both these interfaces have to be created. +IP Event: Transmit/Receive Packet +--------------------------------- + +This event, ``IP_EVENT_TX_RX``, is triggered for every transmitted or received IP packet. It provides information about packet transmission or reception, data length, and the ``esp_netif`` handle. + +Enabling the Event +------------------ + +**Compile Time:** + +The feature can be completely disabled during compilation time using the flag :ref:`CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC` in the kconfig. + +**Run Time:** + +At runtime, you can enable or disable this event using the functions :cpp:func:`esp_netif_tx_rx_event_enable()` and :cpp:func:`esp_netif_tx_rx_event_disable()`. + +Event Registration +------------------ + +To handle this event, you need to register a handler using the following syntax: + +.. code-block:: c + + static void + tx_rx_event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) + { + ip_event_tx_rx_t *event = (ip_event_tx_rx_t *)event_data; + + if (event->dir == ESP_NETIF_TX) { + ESP_LOGI(TAG, "Got TX event: Interface \"%s\" data len: %d", esp_netif_get_desc(event->esp_netif), event->len); + } else if (event->dir == ESP_NETIF_RX) { + ESP_LOGI(TAG, "Got RX event: Interface \"%s\" data len: %d", esp_netif_get_desc(event->esp_netif), event->len); + } else { + ESP_LOGI(TAG, "Got Unknown event: Interface \"%s\"", esp_netif_get_desc(event->esp_netif)); + } + } + + esp_event_handler_register(IP_EVENT, IP_EVENT_TX_RX, &tx_rx_event_handler, NULL); + +Here, ``tx_rx_event_handler`` is the name of the function that will handle the event. + +Event Data Structure +--------------------- + +The event data structure, :cpp:class:`ip_event_tx_rx_t`, contains the following fields: + +- :cpp:member:`ip_event_tx_rx_t::dir`: Indicates whether the packet was transmitted (``ESP_NETIF_TX``) or received (``ESP_NETIF_RX``). +- :cpp:member:`ip_event_tx_rx_t::len`: Length of the data frame. +- :cpp:member:`ip_event_tx_rx_t::esp_netif`: The network interface on which the packet was sent or received. + + API Reference -------------