diff --git a/components/esp_netif/include/esp_netif_net_stack.h b/components/esp_netif/include/esp_netif_net_stack.h index 334183a11..c38297a9f 100644 --- a/components/esp_netif/include/esp_netif_net_stack.h +++ b/components/esp_netif/include/esp_netif_net_stack.h @@ -62,8 +62,10 @@ void* esp_netif_get_netif_impl(esp_netif_t *esp_netif); * This function gets called from network stack to output packets to IO driver. * * @param[in] esp_netif Handle to esp-netif instance - * @param[in] data Data to be tranmitted + * @param[in] data Data to be transmitted * @param[in] len Length of the data frame + * + * @return ESP_OK on success, an error passed from the I/O driver otherwise */ esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len); @@ -75,7 +77,7 @@ esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len); * to avoid copying) * * @param[in] esp_netif Handle to esp-netif instance - * @param[in] void* buffer: rx buffer pointer + * @param[in] buffer Rx buffer pointer */ void esp_netif_free_rx_buffer(void *esp_netif, void* buffer); diff --git a/docs/Doxyfile b/docs/Doxyfile index a6f301cf5..c880f3b68 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -28,6 +28,7 @@ INPUT = \ ../../components/esp_wifi/include/esp_wifi_types.h \ ../../components/esp_wifi/include/esp_smartconfig.h \ ../../components/esp_wifi/include/esp_now.h \ + ../../components/esp_wifi/include/esp_wifi_default.h \ ## Mesh - API Reference ../../components/esp_wifi/include/esp_mesh.h \ ## Event loop - API Reference @@ -127,6 +128,7 @@ INPUT = \ ../../components/soc/esp32/include/soc/rtc_io_channel.h \ ## esp_netif - API Reference ../../components/esp_netif/include/esp_netif.h \ + ../../components/esp_netif/include/esp_netif_net_stack.h \ ## ## Protocols - API Reference ## diff --git a/docs/en/api-reference/network/esp_netif.rst b/docs/en/api-reference/network/esp_netif.rst index da44cbbd0..ea159c08c 100644 --- a/docs/en/api-reference/network/esp_netif.rst +++ b/docs/en/api-reference/network/esp_netif.rst @@ -90,10 +90,6 @@ B) Interaction with network interfaces using ESP-NETIF API * Receiving IP events (connect/disconnect) * Controlling application lifecycle (set interface up/down) -Please note that the initialization code as well as registering event handlers for default interfaces, -such as WiFi softAP and WiFi station, are provided as a separate APIs (for example ``esp_netif_create_default_wifi_ap()`` and -``esp_netif_create_default_wifi_sta()``) to facilitate simple startup code for most applications. - B) Communication driver, IO driver, media driver ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +101,7 @@ Communication driver plays these two important roles in relation with ESP-NETIF: 2) Glue IO layer: Adapts the input/output functions to use ESP-NETIF transmit, receive and free receive buffer * Installs driver_transmit to appropriate ESP-NETIF object, so that outgoing packets from network stack are passed to the IO driver - * Calls ``esp_netif_receive()`` to pass incoming data to network stack + * Calls :cpp:func:`esp_netif_receive()` to pass incoming data to network stack C) ESP-NETIF, former tcpip_adapter @@ -140,9 +136,42 @@ Network stack has no public interaction with application code with regard to pub ESP-NETIF API. +ESP-NETIF programmer's manual +----------------------------- + +Please refer to the example section for basic initialization of default interfaces: + +- WiFi Station: :example:`examples/wifi/getting_started/station/main/station_example_main.c` +- WiFi Access Point: :example:`examples/wifi/getting_started/softAP/main/softap_example_main.c` +- Ethernet :example:`examples/ethernet/basic/main/ethernet_example_main.c` + +For more specific cases please consult this guide: :doc:`/api-reference/network/esp_netif_driver`. + + +WiFi default initialization +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The initialization code as well as registering event handlers for default interfaces, +such as softAP and station, are provided in two separate APIs to facilitate simple startup code for most applications: + +* :cpp:func:`esp_netif_create_default_wifi_ap()` +* :cpp:func:`esp_netif_create_default_wifi_sta()` + +Please note that these functions return the ``esp_netif`` handle, i.e. a pointer to a network interface object allocated and +configured with default settings, which as a consequence, means that: + +* The created object has to be destroyed if a network de-initialization is provided by an application. +* These *default* interfaces must not be created multiple times, unless the created handle is deleted using :cpp:func:`esp_netif_destroy()`. +* When using Wifi in ``AP+STA`` mode, both these interfaces has to be created. + API Reference ------------- .. include:: /_build/inc/esp_netif.inc + +WiFi default API reference +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. include:: /_build/inc/esp_wifi_default.inc diff --git a/docs/en/api-reference/network/esp_netif_driver.rst b/docs/en/api-reference/network/esp_netif_driver.rst new file mode 100644 index 000000000..4dd7f1c6a --- /dev/null +++ b/docs/en/api-reference/network/esp_netif_driver.rst @@ -0,0 +1,97 @@ +ESP-NETIF Custom I/O Driver +=========================== + +This section outlines implementing a new I/O driver with esp-netif connection capabilities. +By convention the I/O driver has to register itself as an esp-netif driver and thus holds a dependency on esp-netif component +and is responsible for providing data path functions, post-attach callback and in most cases also default event handlers to define network interface +actions based on driver's lifecycle transitions. + + +Packet input/output +^^^^^^^^^^^^^^^^^^^ + +As shown in the diagram, the following three API functions for the packet data path must be defined for connecting with esp-netif: + +* :cpp:func:`esp_netif_transmit()` +* :cpp:func:`esp_netif_free_rx_buffer()` +* :cpp:func:`esp_netif_receive()` + +The first two functions for transmitting and freeing the rx buffer are provided as callbacks, i.e. they get called from +esp-netif (and its underlying TCP/IP stack) and I/O driver provides their implementation. + +The receiving function on the other hand gets called from the I/O driver, so that the driver's code simply calls :cpp:func:`esp_netif_receive()` +on a new data received event. + + +Post attach callback +^^^^^^^^^^^^^^^^^^^^ + +A final part of the network interface initialization consists of attaching the esp-netif instance to the I/O driver, by means +of calling the following API: + +.. code:: c + + esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle driver_handle); + +It is assumed that the ``esp_netif_iodriver_handle`` is a pointer to driver's object, a struct derived from ``struct esp_netif_driver_base_s``, +so that the first member of I/O driver structure must be this base structure with pointers to + +* post-attach function callback +* related esp-netif instance + +As a consequence the I/O driver has to create an instance of the struct per below: + +.. code:: c + + typedef struct my_netif_driver_s { + esp_netif_driver_base_t base; /*!< base structure reserved as esp-netif driver */ + driver_impl *h; /*!< handle of driver implementation */ + } my_netif_driver_t; + +with actual values of ``my_netif_driver_t::base.post_attach`` and the actual drivers handle ``my_netif_driver_t::h``. +So when the :cpp:func:`esp_netif_attach()` gets called from the initialization code, the post-attach callback from I/O driver's code +gets executed to mutually register callbacks between esp-netif and I/O driver instances. Typically the driver is started +as well in the post-attach callback. An example of a simple post-attach callback is outlined below: + +.. code:: c + + static esp_err_t my_post_attach_start(esp_netif_t * esp_netif, void * args) + { + my_netif_driver_t *driver = args; + const esp_netif_driver_ifconfig_t driver_ifconfig = { + .driver_free_rx_buffer = my_free_rx_buf, + .transmit = my_transmit, + .handle = driver->driver_impl + }; + driver->base.netif = esp_netif; + ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig)); + my_driver_start(driver->driver_impl); + return ESP_OK; + } + + +Default handlers +^^^^^^^^^^^^^^^^ + +I/O drivers also typically provide default definitions of lifecycle behaviour of related network interfaces based +on state transitions of I/O drivers. For example *driver start* ``->`` *network start*, etc. +An example of such a default handler is provided below: + +.. code:: c + + esp_err_t my_driver_netif_set_default_handlers(my_netif_driver_t *driver, esp_netif_t * esp_netif) + { + driver_set_event_handler(driver->driver_impl, esp_netif_action_start, MY_DRV_EVENT_START, esp_netif); + driver_set_event_handler(driver->driver_impl, esp_netif_action_stop, MY_DRV_EVENT_STOP, esp_netif); + return ESP_OK; + } + + +Network stack connection +------------------------ + +The packet data path functions for transmitting and freeing the rx buffer (defined in the I/O driver) are called from +the esp-netif, specifically from its TCP/IP stack connecting layer. The following API reference outlines these network stack +interaction with the esp-netif. + +.. include:: /_build/inc/esp_netif_net_stack.inc diff --git a/docs/en/api-reference/network/index.rst b/docs/en/api-reference/network/index.rst index ab2bb3a73..82db052c2 100644 --- a/docs/en/api-reference/network/index.rst +++ b/docs/en/api-reference/network/index.rst @@ -42,6 +42,7 @@ IP Network Layer :hidden: TCP/IP Adapter Migration Guide + ESP-NETIF Custom I/O Driver Code examples for TCP/IP socket APIs are provided in the :example:`protocols/sockets` directory of ESP-IDF examples. diff --git a/docs/zh_CN/api-reference/network/esp_netif_driver.rst b/docs/zh_CN/api-reference/network/esp_netif_driver.rst new file mode 100644 index 000000000..127e5dcce --- /dev/null +++ b/docs/zh_CN/api-reference/network/esp_netif_driver.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-reference/network/esp_netif_driver.rst diff --git a/docs/zh_CN/api-reference/network/index.rst b/docs/zh_CN/api-reference/network/index.rst index 55c7ef168..57964dcca 100644 --- a/docs/zh_CN/api-reference/network/index.rst +++ b/docs/zh_CN/api-reference/network/index.rst @@ -37,7 +37,12 @@ IP 网络层协议 :maxdepth: 1 ESP-NETIF + +.. toctree:: + :hidden: + TCP/IP Adapter Migration Guide + ESP-NETIF Custom I/O Driver TCP/IP 套接字 API 的示例代码存放在 ESP-IDF 示例项目的 :example:`protocols/sockets` 目录下。