mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-15 11:36:33 +02:00
docs(common): improving documentation
- update esp_modem to use esp_docs - migrated docs from github pages to docs.espressif.com
This commit is contained in:
@ -1,73 +0,0 @@
|
||||
# This is Doxygen configuration file
|
||||
#
|
||||
# Doxygen provides over 260 configuration statements
|
||||
# To make this file easier to follow,
|
||||
# it contains only statements that are non-default
|
||||
#
|
||||
# NOTE:
|
||||
# It is recommended not to change defaults unless specifically required
|
||||
# Test any changes how they affect generated documentation
|
||||
# Make sure that correct warnings are generated to flag issues with documented code
|
||||
#
|
||||
# For the complete list of configuration statements see:
|
||||
# http://doxygen.nl/manual/config.html
|
||||
|
||||
|
||||
PROJECT_NAME = "ESP Protocols Programming Guide"
|
||||
|
||||
## The 'INPUT' statement below is used as input by script 'gen-df-input.py'
|
||||
## to automatically generate API reference list files heder_file.inc
|
||||
## These files are placed in '_inc' directory
|
||||
## and used to include in API reference documentation
|
||||
|
||||
|
||||
## Get warnings for functions that have no documentation for their parameters or return value
|
||||
##
|
||||
WARN_NO_PARAMDOC = YES
|
||||
|
||||
## Enable preprocessing and remove __attribute__(...) expressions from the INPUT files
|
||||
##
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = \
|
||||
$(ENV_DOXYGEN_DEFINES) \
|
||||
__DOXYGEN__=1 \
|
||||
__attribute__(x)= \
|
||||
_Static_assert()= \
|
||||
IDF_DEPRECATED(X)= \
|
||||
IRAM_ATTR= \
|
||||
configSUPPORT_DYNAMIC_ALLOCATION=1 \
|
||||
configSUPPORT_STATIC_ALLOCATION=1 \
|
||||
configQUEUE_REGISTRY_SIZE=1 \
|
||||
configUSE_RECURSIVE_MUTEXES=1 \
|
||||
configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS=1 \
|
||||
configNUM_THREAD_LOCAL_STORAGE_POINTERS=1 \
|
||||
configUSE_APPLICATION_TASK_TAG=1 \
|
||||
configTASKLIST_INCLUDE_COREID=1 \
|
||||
"ESP_EVENT_DECLARE_BASE(x)=extern esp_event_base_t x"
|
||||
|
||||
## Do not complain about not having dot
|
||||
##
|
||||
HAVE_DOT = NO
|
||||
|
||||
## Generate XML that is required for Breathe
|
||||
##
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = xml
|
||||
|
||||
GENERATE_HTML = NO
|
||||
HAVE_DOT = NO
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_MAN = YES
|
||||
GENERATE_RTF = NO
|
||||
|
||||
## Skip distracting progress messages
|
||||
##
|
||||
QUIET = YES
|
||||
|
||||
## Enable Section Tags for conditional documentation
|
||||
##
|
||||
ENABLED_SECTIONS += \
|
||||
DOC_EXCLUDE_HEADER_SECTION \ ## To conditionally remove doc sections from IDF source files without affecting documentation in upstream files.
|
||||
DOC_SINGLE_GROUP ## To conditionally remove groups from the documentation and create a 'flat' document without affecting documentation in upstream files.
|
@ -1,22 +0,0 @@
|
||||
from esp_docs.conf_docs import * # noqa: F403,F401
|
||||
|
||||
extensions += [
|
||||
'sphinx_copybutton',
|
||||
# Needed as a trigger for running doxygen
|
||||
'esp_docs.esp_extensions.dummy_build_system',
|
||||
'esp_docs.esp_extensions.run_doxygen',
|
||||
]
|
||||
|
||||
# link roles config
|
||||
github_repo = 'espressif/esp-protocols'
|
||||
|
||||
# context used by sphinx_idf_theme
|
||||
html_context['github_user'] = 'espressif'
|
||||
html_context['github_repo'] = 'esp-protocols'
|
||||
|
||||
# Extra options required by sphinx_idf_theme
|
||||
project_slug = 'esp-idf' # >=5.0
|
||||
versions_url = 'https://github.com/espressif/esp-protocols/docs/docs_versions.js'
|
||||
|
||||
idf_targets = ['esp32']
|
||||
languages = ['en', 'zh_CN']
|
@ -1,24 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
#
|
||||
# Uses ../conf_common.py for most non-language-specific settings.
|
||||
|
||||
# Importing conf_common adds all the non-language-specific
|
||||
# parts to this conf module
|
||||
|
||||
try:
|
||||
from conf_common import * # noqa: F403,F401
|
||||
except ImportError:
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('../'))
|
||||
from conf_common import * # noqa: F403,F401
|
||||
|
||||
# General information about the project.
|
||||
project = u'ESP-Protocols'
|
||||
copyright = u'2016 - 2022, Espressif Systems (Shanghai) Co., Ltd'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
language = 'en'
|
@ -1,42 +0,0 @@
|
||||
ASIO port
|
||||
=========
|
||||
|
||||
Overview
|
||||
--------
|
||||
Asio is a cross-platform C++ library, see https://think-async.com/Asio/. It provides a consistent asynchronous model using a modern C++ approach.
|
||||
|
||||
|
||||
ASIO documentation
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
Please refer to the original asio documentation at https://think-async.com/Asio/Documentation.
|
||||
Asio also comes with a number of examples which could be find under Documentation/Examples on that web site.
|
||||
|
||||
Supported features
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
ESP platform port currently supports only network asynchronous socket operations; does not support serial port.
|
||||
SSL/TLS support is disabled by default and could be enabled in component configuration menu by choosing TLS library from
|
||||
|
||||
- mbedTLS with OpenSSL translation layer (default option)
|
||||
- wolfSSL
|
||||
|
||||
SSL support is very basic at this stage and it does include following features:
|
||||
|
||||
- Verification callbacks
|
||||
- DH property files
|
||||
- Certificates/private keys file APIs
|
||||
|
||||
Internal asio settings for ESP include
|
||||
|
||||
- EXCEPTIONS are enabled in ASIO if enabled in menuconfig
|
||||
- TYPEID is enabled in ASIO if enabled in menuconfig
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
ESP examples are based on standard asio :example:`examples <../examples>`:
|
||||
|
||||
- :example:`udp_echo_server <../examples/udp_echo_server>`
|
||||
- :example:`tcp_echo_server <../examples/tcp_echo_server>`
|
||||
- :example:`asio_chat <../examples/asio_chat>`
|
||||
- :example:`ssl_client_server <../examples/ssl_client_server>`
|
||||
|
||||
Please refer to the specific example README.md for details
|
@ -1,26 +0,0 @@
|
||||
build-docs --target esp32 --language en
|
||||
|
||||
cp -rf _build/en/esp32/html .
|
||||
rm -rf _build __pycache__
|
||||
|
||||
# Modifes some version and target fields of index.html
|
||||
echo "<script type="text/javascript">
|
||||
window.onload =(function() {
|
||||
var myAnchor = document.getElementById('version-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.setAttribute('type', 'text');
|
||||
mySpan.setAttribute('maxLength', '10');
|
||||
mySpan.value = 'latest';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
|
||||
var myAnchor = document.getElementById('target-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.setAttribute('type', 'text');
|
||||
mySpan.setAttribute('maxLength', '10');
|
||||
mySpan.value = 'all targets';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
|
||||
})();
|
||||
</script>" >> html/index.html
|
@ -1,27 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
#
|
||||
# Uses ../conf_common.py for most non-language-specific settings.
|
||||
|
||||
# Importing conf_common adds all the non-language-specific
|
||||
# parts to this conf module
|
||||
try:
|
||||
from conf_common import * # noqa: F403,F401
|
||||
except ImportError:
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
from conf_common import * # noqa: F403,F401
|
||||
|
||||
import datetime
|
||||
|
||||
current_year = datetime.datetime.now().year
|
||||
|
||||
# General information about the project.
|
||||
project = u'ESP-IDF 编程指南'
|
||||
copyright = u'2016 - {} 乐鑫信息科技(上海)股份有限公司'.format(current_year)
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
language = 'zh_CN'
|
@ -1 +0,0 @@
|
||||
.. include:: ../../../en/api-reference/protocols/asio.rst
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
Binary file not shown.
Before Width: | Height: | Size: 139 KiB |
File diff suppressed because it is too large
Load Diff
@ -1,92 +0,0 @@
|
||||
# ESP MODEM
|
||||
|
||||
This component is used to communicate with modems in the command mode (using AT commands), as well as the data mode
|
||||
(over PPPoS protocol).
|
||||
The modem device is modeled with a DCE (Data Communication Equipment) object, which is composed of:
|
||||
* DTE (Data Terminal Equipment), which abstracts the terminal (currently only UART implemented).
|
||||
* PPP Netif representing a network interface communicating with the DTE using PPP protocol.
|
||||
* Module abstracting the specific device model and its commands.
|
||||
|
||||
```
|
||||
+-----+
|
||||
| DTE |--+
|
||||
+-----+ | +-------+
|
||||
+-->| DCE |
|
||||
+-------+ | |o--- set_mode(command/data)
|
||||
| Module|--->| |
|
||||
+-------+ | |o--- send_commands
|
||||
+->| |
|
||||
+------+ | +-------+
|
||||
| PPP |--+
|
||||
| netif|------------------> network events
|
||||
+------+
|
||||
```
|
||||
|
||||
## Modem components
|
||||
### DCE
|
||||
|
||||
This is the basic operational unit of the esp_modem component, abstracting a specific module in software,
|
||||
which is basically configured by
|
||||
* the I/O communication media (UART), defined by the DTE configuration
|
||||
* the specific command library supported by the device model, defined with the module type
|
||||
* network interface configuration (PPPoS config in lwip)
|
||||
|
||||
After the object is created, the application interaction with the DCE is in
|
||||
* issuing specific commands to the modem
|
||||
* switching between data and command mode
|
||||
|
||||
### DTE
|
||||
Is an abstraction of the physical interface connected to the modem. Current implementation supports only UART
|
||||
|
||||
### PPP netif
|
||||
|
||||
Is used to attach the specific network interface to a network communication protocol used by the modem. Currently implementation supports only PPPoS protocol.
|
||||
|
||||
### Module
|
||||
|
||||
Abstraction of the specific modem device. Currently the component supports SIM800, BG96, SIM7600.
|
||||
|
||||
## Use cases
|
||||
|
||||
Users interact with the esp-modem using the DCE's interface, to basically
|
||||
* Switch between command and data mode to connect to the internet via cellular network.
|
||||
* Send various commands to the device (e.g. send SMS)
|
||||
|
||||
The applications typically register handlers for network events to receive notification on the network availability and
|
||||
IP address changes.
|
||||
|
||||
Common use cases of the esp-modem are also listed as the examples:
|
||||
* `examples/pppos_client` -- simple client which reads some module properties and switches to the data mode to connect to a public mqtt broker.
|
||||
* `examples/modem_console` -- is an example to exercise all possible module commands in a console application.
|
||||
* `examples/ap_to_pppos` -- this example focuses on the network connectivity of the esp-modem and provides a WiFi AP that forwards packets (and uses NAT) to and from the PPPoS connection.
|
||||
|
||||
## Extensibility
|
||||
|
||||
### CMUX
|
||||
|
||||
Implementation of virtual terminals is an experimental feature, which allows users to also issue commands in the data mode,
|
||||
after creating multiple virtual terminals, designating some of them solely to data mode, others solely to command mode.
|
||||
|
||||
### DTE's
|
||||
|
||||
Currently, we support only UART (and USB as a preview feature), but modern modules support other communication interfaces, such as USB, SPI.
|
||||
|
||||
### Other devices
|
||||
|
||||
Adding a new device is a must-have requirement for the esp-modem component. Different modules support different commands,
|
||||
or some commands might have a different implementation. Adding a new device means to provide a new implementation
|
||||
as a class derived from `GenericModule`, where we could add new commands or modify the existing ones.
|
||||
|
||||
## Configuration
|
||||
|
||||
Modem abstraction is configurable both compile-time and run-time.
|
||||
|
||||
### Component Kconfig
|
||||
|
||||
Compile-time configuration is provided using menuconfig. Please check the description for the CMUX mode configuration options.
|
||||
|
||||
### Runtime configuration
|
||||
|
||||
Is defined using standard configuration structures for `DTE` and `DCE` objects separately. Please find documentation of
|
||||
* :cpp:class:`esp_modem_dte_config_t`
|
||||
* :cpp:class:`esp_modem_dce_config_t`
|
@ -1,48 +0,0 @@
|
||||
Advanced esp-modem use cases
|
||||
============================
|
||||
|
||||
This chapter outlines basic extensibility of the esp-modem component.
|
||||
|
||||
.. _dce_factory:
|
||||
|
||||
Custom instantiation with DCE factory
|
||||
--------------------------------------
|
||||
|
||||
It is possible to create a modem handle in many different ways:
|
||||
|
||||
- Build a DCE on top a generic module, user defined module or build the module only (in case the application will only use AT command interface)
|
||||
- Create the DCE as a shared, unique or a vanilla pointer
|
||||
- Create a generic DCE or a templated DCE_T of a specific module (this could be one of the supported modules or a user defined module)
|
||||
|
||||
All the functionality is provided by the DCE factory
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_DCE_FACTORY
|
||||
:members:
|
||||
|
||||
.. _create_custom_module:
|
||||
|
||||
Create custom module
|
||||
--------------------
|
||||
|
||||
Creating a custom module is necessary if the application needs to use a specific device that is not supported
|
||||
and their commands differ from any of the supported devices. In this case it is recommended to define a new class
|
||||
representing this specific device and derive from the :cpp:class:`esp_modem::GenericModule`. In order to instantiate
|
||||
the appropriate DCE of this module, application could use :ref:`the DCE factory<dce_factory>`, and build the DCE with
|
||||
the specific module, using :cpp:func:`esp_modem::dce_factory::Factory::build`.
|
||||
|
||||
Please refer to the implementation of the existing modules.
|
||||
|
||||
Please note that the ``modem_console`` example defines a trivial custom modem DCE which overrides one command,
|
||||
for demonstration purposes only.
|
||||
|
||||
|
||||
Create new communication interface
|
||||
----------------------------------
|
||||
|
||||
In order to connect to a device using an unsupported interface (e.g. SPI or I2C), it is necessary to implement
|
||||
a custom DTE object and supply it into :ref:`the DCE factory<dce_factory>`. The DCE is typically created in two steps:
|
||||
|
||||
- Define and create the corresponding terminal, which communicates on the custom interface. This terminal should support basic IO methods defined in :cpp:class:`esp_modem::Terminal` and derive from it.
|
||||
- Create the DTE which uses the custom Terminal
|
||||
|
||||
Please refer to the implementation of the existing UART DTE.
|
@ -1,57 +0,0 @@
|
||||
.. _c_api:
|
||||
|
||||
C API Documentation
|
||||
===================
|
||||
|
||||
|
||||
The C API is very simple and consist of these two basic parts:
|
||||
|
||||
- :ref:`lifecycle_api`
|
||||
- :ref:`modem_commands`
|
||||
|
||||
The Typical application workflow is to:
|
||||
|
||||
- Create a DCE instance (using :cpp:func:`esp_modem_new`)
|
||||
- Call specific functions to issue AT commands (:ref:`modem_commands`)
|
||||
- Switch to the data mode (using :cpp:func:`esp_modem_set_mode`)
|
||||
- Perform desired network operations (using standard networking API, unrelated to ESP-MODEM)
|
||||
- Optionally switch back to command mode (again :cpp:func:`esp_modem_set_mode`)
|
||||
- Destroy the DCE handle (sing :cpp:func:`esp_modem_destroy`)
|
||||
|
||||
Note the configuration structures for DTE and DCE, needed for creating the DCE instance, is documented in :ref:`api_config`
|
||||
|
||||
.. _lifecycle_api:
|
||||
|
||||
Lifecycle API
|
||||
-------------
|
||||
|
||||
These functions are used to create, destroy and set modem working mode.
|
||||
|
||||
- :cpp:func:`esp_modem_new`
|
||||
- :cpp:func:`esp_modem_destroy`
|
||||
- :cpp:func:`esp_modem_set_mode`
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_C_API
|
||||
|
||||
|
||||
.. _modem_commands:
|
||||
|
||||
Modem commands
|
||||
--------------
|
||||
|
||||
These functions are the actual commands to communicate with the modem using AT command interface.
|
||||
|
||||
Note that the functions which implement AT commands returning textual values use plain ``char *``
|
||||
pointer as the return value. The API expects the output data to point to user allocated space of at least
|
||||
``ESP_MODEM_C_API_STR_MAX`` (64 by default) bytes, it also truncates the output data to this size.
|
||||
|
||||
.. doxygenfile:: esp_modem_api_commands.h
|
||||
|
||||
.. _api_config:
|
||||
|
||||
Configuration structures
|
||||
------------------------
|
||||
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_CONFIG
|
||||
:members:
|
@ -1,24 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
#
|
||||
|
||||
# General information about the project.
|
||||
project = u'esp-modem'
|
||||
copyright = u'2016 - 2021, Espressif Systems (Shanghai) Co., Ltd'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
language = 'en'
|
||||
|
||||
extensions = ['breathe', 'recommonmark']
|
||||
|
||||
breathe_projects = {'esp_modem': 'xml'}
|
||||
|
||||
breathe_default_project = 'esp_modem'
|
||||
|
||||
source_suffix = ['.rst', '.md']
|
||||
|
||||
source_parsers = {
|
||||
'.md': 'recommonmark.parser.CommonMarkParser',
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
C++ API Documentation
|
||||
=====================
|
||||
|
||||
Similar to the :ref:`c_api`, the basic application workflow consist of
|
||||
|
||||
.. toctree::
|
||||
|
||||
- :ref:`Construction of the DCE<cpp_init>`
|
||||
- :ref:`Switching modes<cpp_mode_switch>`
|
||||
- :ref:`Sending (AT) commands<cpp_modem_commands>`
|
||||
- :ref:`Destroying the DCE<cpp_destroy>`
|
||||
|
||||
.. _cpp_init:
|
||||
|
||||
Create DTE and DCE
|
||||
------------------
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_INIT_DTE
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_INIT_DCE
|
||||
|
||||
|
||||
.. _cpp_mode_switch:
|
||||
|
||||
Mode switching commands
|
||||
-----------------------
|
||||
|
||||
.. doxygenclass:: esp_modem::DCE_T
|
||||
:members:
|
||||
|
||||
.. _cpp_modem_commands:
|
||||
|
||||
Modem commands
|
||||
--------------
|
||||
|
||||
.. include:: cxx_api_links.rst
|
||||
|
||||
.. _cpp_destroy:
|
||||
|
||||
Destroy the DCE
|
||||
---------------
|
||||
|
||||
The DCE object is created as ``std::unique_ptr`` by default and as such doesn't have to be explicitly destroyed.
|
||||
It simply gets destroyed and cleaned-up automatically if the object goes out of the block scope.
|
@ -1,23 +0,0 @@
|
||||
# Cleanup the generated html
|
||||
rm -rf html
|
||||
|
||||
# Cleans example and test build dirs (to reduce the component size before upload)
|
||||
rm -rf ../examples/ap_to_pppos/build/ ../examples/simple_cmux_client/build/ ../examples/pppos_client/build/ ../examples/linux_modem/build/ ../examples/modem_console/build ../test/host_test/build/ ../test/target/build/
|
||||
|
||||
# Generate C++ API header of the DCE
|
||||
cat ../include/generate/esp_modem_command_declare.inc | clang++ -E -P -CC -xc++ -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' > esp_modem_dce.hpp
|
||||
|
||||
# Generate C API header of the modem_api.h
|
||||
cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -CC -xc -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' > esp_modem_api_commands.h
|
||||
|
||||
# RST with links to C++ API
|
||||
cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -xc -I../include -DGENERATE_DOCS -DGENERATE_RST_LINKS - | sed 's/NL/\n/g' > cxx_api_links.rst
|
||||
|
||||
# Run doxygen
|
||||
doxygen
|
||||
|
||||
# Generate the docs
|
||||
python -u -m sphinx.cmd.build -b html . html
|
||||
|
||||
# Cleanup the doxygen xml's and temporary headers
|
||||
rm -rf xml esp_modem_api_commands.h esp_modem_dce.hpp cxx_api_links.rst
|
@ -1,11 +0,0 @@
|
||||
ESP-MODEM Programmers manual
|
||||
============================
|
||||
|
||||
.. toctree::
|
||||
|
||||
Brief intro <README>
|
||||
C interface <api_docs>
|
||||
C++ interface <cxx_api_docs>
|
||||
Advanced use cases <advanced_api>
|
||||
Internal design <internal_design>
|
||||
Internal implementation <internal_docs>
|
@ -1,36 +0,0 @@
|
||||
# Internal design
|
||||
|
||||
## Design decisions
|
||||
|
||||
* Use C++ with additional C API
|
||||
|
||||
* Use exceptions
|
||||
- Use macro wrapper over `try-catch` blocks when exceptions off (use `abort()` if `THROW()`)
|
||||
|
||||
* Initializes and allocates in the constructor (might throw)
|
||||
- easier code with exceptions ON, with exceptions OFF alloc/init failures are not treated as runtime error (program aborts)
|
||||
- break down long initialization in constructor into more private methods
|
||||
|
||||
* Implements different devices using inheritance from `GenericModule`, which is the most general implementation of a common modem
|
||||
- Internally uses templates with device specialization (modeled as `DCE<SpecificModule>`) which could be used as well for some special cases,
|
||||
such as implantation of a minimal device (ModuleIf), add new AT commands (oOnly in compile time), or using the Module with DTE only (no DCE, no Netif) for sending AT commands without network
|
||||
|
||||
## DCE collaboration model
|
||||
|
||||
The diagram describes how the DCE class collaborates with DTE, PPP and the device abstraction
|
||||
|
||||

|
||||
|
||||
## Terminal inheritance
|
||||
|
||||
Terminal is a class which can read or write data, and can handle callbacks when data are available. UART specialization
|
||||
is provided implementing these method using the uart driver.
|
||||
|
||||
## CMUX terminal
|
||||
|
||||
The below diagram depicts the idea of using CMUX terminal mode using the CMuxInstance class which is a terminal
|
||||
(it implements the basic read/write methods) interfacing arbitrary number of virtual terminals,
|
||||
but at the same time it is also composed of CMux class, which consumes the original terminal and uses its read/write methods
|
||||
to multiplex the terminal.
|
||||
|
||||

|
@ -1,117 +0,0 @@
|
||||
DCE Internal implementation
|
||||
===========================
|
||||
|
||||
This chapter provides a detailed description of the classes and building blocks of the esp-modem component and their responsibilities.
|
||||
|
||||
The esp-modem actually implements the DCE class, which in turn aggregates these thee units:
|
||||
|
||||
- :ref:`DTE<dte_impl>` to communicate with the device on a specific Terminal interface such as UART.
|
||||
- :ref:`Netif<netif_impl>` to provide the network connectivity
|
||||
- :ref:`Module<module_impl>` to define the specific command library
|
||||
|
||||
Developers would typically have to
|
||||
|
||||
* Add support for a new module
|
||||
* Implement a generic (common for all modules) AT command
|
||||
|
||||
This is explained in the :ref:`Module<module_impl>` section, as :ref:`Adding new module or command<module_addition>`
|
||||
|
||||
------------
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_DCE
|
||||
:members:
|
||||
|
||||
.. _dte_impl:
|
||||
|
||||
DTE abstraction
|
||||
---------------
|
||||
|
||||
DTE is a basic unit to talk to the module using a Terminal interface. It also implements and uses the CMUX to multiplex
|
||||
terminals. Besides the DTE documentation, this section also refers to the
|
||||
|
||||
- :ref:`Terminal interface<term_impl>`
|
||||
- :ref:`CMUX implementation<cmux_impl>`
|
||||
|
||||
|
||||
------------
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_DTE
|
||||
:members:
|
||||
|
||||
.. _term_impl:
|
||||
|
||||
Terminal interface
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_TERMINAL
|
||||
:members:
|
||||
|
||||
.. _cmux_impl:
|
||||
|
||||
CMUX implementation
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_CMUX
|
||||
:members:
|
||||
|
||||
.. _netif_impl:
|
||||
|
||||
Netif
|
||||
-----
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_NETIF
|
||||
:members:
|
||||
|
||||
.. _module_impl:
|
||||
|
||||
Module abstraction
|
||||
------------------
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_MODULE
|
||||
:members:
|
||||
|
||||
.. _module_addition:
|
||||
|
||||
Adding new devices
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To support a new module, developers would have to implement a new class derived from :cpp:class:`esp_modem::GenericModule` the same way
|
||||
as it is described in the :ref:`Advanced user manual<create_custom_module>`. The only difference is that the new class (and factory extension)
|
||||
would be available in the esp_modem code base.
|
||||
|
||||
Implement a new generic command
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Adding a generic command, i.e. the command that is shared for all modules and is included in the :cpp:class:`esp_modem::GenericModule`,
|
||||
has to be declared first in the ``include/generate/esp_modem_command_declare.inc`` file, which is the single source
|
||||
of supported command definitions, that is used in:
|
||||
|
||||
* public C API
|
||||
* public CPP API
|
||||
* generated documentation
|
||||
* implementation of the command
|
||||
|
||||
Therefore, a care must be taken, to correctly specify all parameters and types, especially:
|
||||
|
||||
* Keep number of parameters low (<= 6, used in preprocessor's forwarding to the command library)
|
||||
* Use macros to specify parameter types (as they are used both from C and C++ with different underlying types)
|
||||
* Parameter names are used only for clarity and documentation, they get expanded to numbered arguments.
|
||||
|
||||
Please use the following pattern: ``INT_IN(p1, baud)``, meaning that the parameter is an input integer,
|
||||
human readable argument name is ``baud``, it's the first argument, so expands to ``p1`` (second argument would be ``p2``, etc)
|
||||
|
||||
Command library
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
This is a namespace holding a library of typical AT commands used by supported devices.
|
||||
Please refer to the :ref:`c_api` for the list of supported commands.
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_DCE_COMMAND
|
||||
:members:
|
||||
|
||||
|
||||
Modem types
|
||||
-----------
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_TYPES
|
||||
:members:
|
@ -1,73 +0,0 @@
|
||||
# This is Doxygen configuration file
|
||||
#
|
||||
# Doxygen provides over 260 configuration statements
|
||||
# To make this file easier to follow,
|
||||
# it contains only statements that are non-default
|
||||
#
|
||||
# NOTE:
|
||||
# It is recommended not to change defaults unless specifically required
|
||||
# Test any changes how they affect generated documentation
|
||||
# Make sure that correct warnings are generated to flag issues with documented code
|
||||
#
|
||||
# For the complete list of configuration statements see:
|
||||
# http://doxygen.nl/manual/config.html
|
||||
|
||||
|
||||
PROJECT_NAME = "MQTT C++ client"
|
||||
|
||||
## The 'INPUT' statement below is used as input by script 'gen-df-input.py'
|
||||
## to automatically generate API reference list files heder_file.inc
|
||||
## These files are placed in '_inc' directory
|
||||
## and used to include in API reference documentation
|
||||
|
||||
INPUT = \
|
||||
$(PROJECT_PATH)/include/esp_mqtt.hpp \
|
||||
$(PROJECT_PATH)/include/esp_mqtt_client_config.hpp
|
||||
|
||||
## Get warnings for functions that have no documentation for their parameters or return value
|
||||
##
|
||||
WARN_NO_PARAMDOC = YES
|
||||
|
||||
## Enable preprocessing and remove __attribute__(...) expressions from the INPUT files
|
||||
##
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = \
|
||||
$(ENV_DOXYGEN_DEFINES) \
|
||||
__DOXYGEN__=1 \
|
||||
__attribute__(x)= \
|
||||
_Static_assert()= \
|
||||
IDF_DEPRECATED(X)= \
|
||||
IRAM_ATTR= \
|
||||
configSUPPORT_DYNAMIC_ALLOCATION=1 \
|
||||
configSUPPORT_STATIC_ALLOCATION=1 \
|
||||
configQUEUE_REGISTRY_SIZE=1 \
|
||||
configUSE_RECURSIVE_MUTEXES=1 \
|
||||
configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS=1 \
|
||||
configNUM_THREAD_LOCAL_STORAGE_POINTERS=1 \
|
||||
configUSE_APPLICATION_TASK_TAG=1 \
|
||||
configTASKLIST_INCLUDE_COREID=1 \
|
||||
"ESP_EVENT_DECLARE_BASE(x)=extern esp_event_base_t x"
|
||||
|
||||
## Do not complain about not having dot
|
||||
##
|
||||
HAVE_DOT = NO
|
||||
|
||||
## Generate XML that is required for Breathe
|
||||
##
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = xml
|
||||
|
||||
GENERATE_HTML = NO
|
||||
HAVE_DOT = NO
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_MAN = YES
|
||||
|
||||
## Skip distracting progress messages
|
||||
##
|
||||
QUIET = YES
|
||||
## Enable Section Tags for conditional documentation
|
||||
##
|
||||
ENABLED_SECTIONS += \
|
||||
DOC_EXCLUDE_HEADER_SECTION ## To conditionally remove doc sections from IDF source files without affecting documentation in upstream files.
|
@ -1,23 +0,0 @@
|
||||
# flake8: noqa
|
||||
from esp_docs.conf_docs import *
|
||||
|
||||
extensions += [
|
||||
'sphinx_copybutton',
|
||||
# Needed as a trigger for running doxygen
|
||||
'esp_docs.esp_extensions.dummy_build_system',
|
||||
'esp_docs.esp_extensions.run_doxygen',
|
||||
]
|
||||
|
||||
# link roles config
|
||||
github_repo = 'espressif/esp-protocols'
|
||||
|
||||
# context used by sphinx_idf_theme
|
||||
html_context['github_user'] = 'espressif'
|
||||
html_context['github_repo'] = 'esp-docs'
|
||||
|
||||
# Extra options required by sphinx_idf_theme
|
||||
project_slug = 'esp-idf' # >=5.0
|
||||
versions_url = 'https://github.com/espressif/esp-protocols/docs/docs_versions.js'
|
||||
|
||||
idf_targets = ['esp32']
|
||||
languages = ['en']
|
@ -1,25 +0,0 @@
|
||||
esp_mqtt_client_config.hpp:line: warning: Compound idf::mqtt::BrokerConfiguration is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Compound idf::mqtt::ClientCredentials is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Compound idf::mqtt::Configuration is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Compound idf::mqtt::Connection is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Compound idf::mqtt::Event is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Compound idf::mqtt::LastWill is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Compound idf::mqtt::Session is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Compound idf::mqtt::Task is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member address (variable) of struct idf::mqtt::BrokerConfiguration is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member security (variable) of struct idf::mqtt::BrokerConfiguration is not documented.
|
||||
esp_mqtt.hpp:line: warning: Member operator()(esp_mqtt_client *client_handler) (function) of struct idf::mqtt::Client::MqttClientDeleter is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member username (variable) of struct idf::mqtt::ClientCredentials is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member authentication (variable) of struct idf::mqtt::ClientCredentials is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member client_id (variable) of struct idf::mqtt::ClientCredentials is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member event (variable) of struct idf::mqtt::Configuration is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member task (variable) of struct idf::mqtt::Configuration is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member session (variable) of struct idf::mqtt::Configuration is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member connection (variable) of struct idf::mqtt::Configuration is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member data (variable) of struct idf::mqtt::DER is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member len (variable) of struct idf::mqtt::DER is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member ds_data (variable) of struct idf::mqtt::DigitalSignatureData is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member data (variable) of struct idf::mqtt::Password is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member data (variable) of struct idf::mqtt::PEM is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member hint_key (variable) of struct idf::mqtt::PSK is not documented.
|
||||
esp_mqtt_client_config.hpp:line: warning: Member last_will (variable) of struct idf::mqtt::Session is not documented.
|
@ -1,24 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
#
|
||||
# Uses ../conf_common.py for most non-language-specific settings.
|
||||
|
||||
# Importing conf_common adds all the non-language-specific
|
||||
# parts to this conf module
|
||||
|
||||
try:
|
||||
from conf_common import * # noqa: F403,F401
|
||||
except ImportError:
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('../'))
|
||||
from conf_common import * # noqa: F403,F401
|
||||
|
||||
# General information about the project.
|
||||
project = u'ESP-Protocols'
|
||||
copyright = u'2016 - 2023, Espressif Systems (Shanghai) Co., Ltd'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
language = 'en'
|
@ -1,132 +0,0 @@
|
||||
ESP MQTT C++ client
|
||||
====================
|
||||
|
||||
Overview
|
||||
--------
|
||||
The ESP MQTT client is a wrapper over the `esp_mqtt` client with the goal of providing a higher level API.
|
||||
|
||||
Features
|
||||
--------
|
||||
* Supports MQTT version 3.11
|
||||
* Adds a Filter validation class for topic filters
|
||||
* Split the event handlers to member functions
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The current design uses exception as an error handling mechanism, therefore exceptions need to be enabled in menuconfig.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
User code needs to inherit fromm :cpp:class:`idf::mqtt::Client` and provide overloads for the event handlers.
|
||||
|
||||
.. note:: The handler is available to allow user code to interact directly with it in case of need. This member will likely be made private in the future once the class API stabilizes.
|
||||
|
||||
|
||||
.. doxygenclass:: idf::mqtt::Client
|
||||
:members:
|
||||
:protected-members:
|
||||
|
||||
Event Handling
|
||||
--------------
|
||||
|
||||
Events are dispatched throug calls to member functions each one dedicated to a type of event.
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
* :example:`tcp <../examples/tcp>`
|
||||
* :example:`ssl <../examples/ssl>`
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
Header File
|
||||
^^^^^^^^^^^
|
||||
|
||||
* :project_file:`include/esp_mqtt.hpp`
|
||||
|
||||
Structures
|
||||
^^^^^^^^^^
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::MQTTException
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::Message
|
||||
:members:
|
||||
|
||||
Classes
|
||||
^^^^^^^
|
||||
|
||||
|
||||
.. doxygenclass:: idf::mqtt::Filter
|
||||
:members:
|
||||
|
||||
Header File
|
||||
^^^^^^^^^^^
|
||||
|
||||
* :project_file:`include/esp_mqtt_client_config.hpp`
|
||||
|
||||
Structures
|
||||
^^^^^^^^^^
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::Host
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::URI
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::BrokerAddress
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::PEM
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::DER
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::Insecure
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::GlobalCAStore
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::PSK
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::Password
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::ClientCertificate
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::SecureElement
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::DigitalSignatureData
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::BrokerConfiguration
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::ClientCredentials
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::Event
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::LastWill
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::Session
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::Task
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::Connection
|
||||
:members:
|
||||
|
||||
.. doxygenstruct:: idf::mqtt::Configuration
|
||||
:members:
|
@ -1,26 +0,0 @@
|
||||
build-docs --target esp32 --language en
|
||||
|
||||
cp -rf _build/en/esp32/html .
|
||||
rm -rf _build __pycache__
|
||||
|
||||
# Modifes some version and target fields of index.html
|
||||
echo "<script type="text/javascript">
|
||||
window.onload =(function() {
|
||||
var myAnchor = document.getElementById('version-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.setAttribute('type', 'text');
|
||||
mySpan.setAttribute('maxLength', '10');
|
||||
mySpan.value = 'latest';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
|
||||
var myAnchor = document.getElementById('target-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.setAttribute('type', 'text');
|
||||
mySpan.setAttribute('maxLength', '10');
|
||||
mySpan.value = 'all targets';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
|
||||
})();
|
||||
</script>" >> html/index.html
|
@ -1,75 +0,0 @@
|
||||
# This is Doxygen configuration file
|
||||
#
|
||||
# Doxygen provides over 260 configuration statements
|
||||
# To make this file easier to follow,
|
||||
# it contains only statements that are non-default
|
||||
#
|
||||
# NOTE:
|
||||
# It is recommended not to change defaults unless specifically required
|
||||
# Test any changes how they affect generated documentation
|
||||
# Make sure that correct warnings are generated to flag issues with documented code
|
||||
#
|
||||
# For the complete list of configuration statements see:
|
||||
# http://doxygen.nl/manual/config.html
|
||||
|
||||
|
||||
PROJECT_NAME = "ESP Protocols Programming Guide"
|
||||
|
||||
## The 'INPUT' statement below is used as input by script 'gen-df-input.py'
|
||||
## to automatically generate API reference list files heder_file.inc
|
||||
## These files are placed in '_inc' directory
|
||||
## and used to include in API reference documentation
|
||||
|
||||
INPUT = \
|
||||
$(PROJECT_PATH)/include/esp_websocket_client.h
|
||||
|
||||
## Get warnings for functions that have no documentation for their parameters or return value
|
||||
##
|
||||
WARN_NO_PARAMDOC = YES
|
||||
|
||||
## Enable preprocessing and remove __attribute__(...) expressions from the INPUT files
|
||||
##
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = \
|
||||
$(ENV_DOXYGEN_DEFINES) \
|
||||
__DOXYGEN__=1 \
|
||||
__attribute__(x)= \
|
||||
_Static_assert()= \
|
||||
IDF_DEPRECATED(X)= \
|
||||
IRAM_ATTR= \
|
||||
configSUPPORT_DYNAMIC_ALLOCATION=1 \
|
||||
configSUPPORT_STATIC_ALLOCATION=1 \
|
||||
configQUEUE_REGISTRY_SIZE=1 \
|
||||
configUSE_RECURSIVE_MUTEXES=1 \
|
||||
configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS=1 \
|
||||
configNUM_THREAD_LOCAL_STORAGE_POINTERS=1 \
|
||||
configUSE_APPLICATION_TASK_TAG=1 \
|
||||
configTASKLIST_INCLUDE_COREID=1 \
|
||||
"ESP_EVENT_DECLARE_BASE(x)=extern esp_event_base_t x"
|
||||
|
||||
## Do not complain about not having dot
|
||||
##
|
||||
HAVE_DOT = NO
|
||||
|
||||
## Generate XML that is required for Breathe
|
||||
##
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = xml
|
||||
|
||||
GENERATE_HTML = NO
|
||||
HAVE_DOT = NO
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_MAN = YES
|
||||
GENERATE_RTF = NO
|
||||
|
||||
## Skip distracting progress messages
|
||||
##
|
||||
QUIET = YES
|
||||
|
||||
## Enable Section Tags for conditional documentation
|
||||
##
|
||||
ENABLED_SECTIONS += \
|
||||
DOC_EXCLUDE_HEADER_SECTION \ ## To conditionally remove doc sections from IDF source files without affecting documentation in upstream files.
|
||||
DOC_SINGLE_GROUP ## To conditionally remove groups from the documentation and create a 'flat' document without affecting documentation in upstream files.
|
@ -1,23 +0,0 @@
|
||||
# flake8: noqa
|
||||
from esp_docs.conf_docs import *
|
||||
|
||||
extensions += [
|
||||
'sphinx_copybutton',
|
||||
# Needed as a trigger for running doxygen
|
||||
'esp_docs.esp_extensions.dummy_build_system',
|
||||
'esp_docs.esp_extensions.run_doxygen',
|
||||
]
|
||||
|
||||
# link roles config
|
||||
github_repo = 'espressif/esp-protocols'
|
||||
|
||||
# context used by sphinx_idf_theme
|
||||
html_context['github_user'] = 'espressif'
|
||||
html_context['github_repo'] = 'esp-docs'
|
||||
|
||||
# Extra options required by sphinx_idf_theme
|
||||
project_slug = 'esp-idf' # >=5.0
|
||||
versions_url = 'https://github.com/espressif/esp-protocols/docs/docs_versions.js'
|
||||
|
||||
idf_targets = ['esp32']
|
||||
languages = ['en']
|
@ -1,24 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
#
|
||||
# Uses ../conf_common.py for most non-language-specific settings.
|
||||
|
||||
# Importing conf_common adds all the non-language-specific
|
||||
# parts to this conf module
|
||||
|
||||
try:
|
||||
from conf_common import * # noqa: F403,F401
|
||||
except ImportError:
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('../'))
|
||||
from conf_common import * # noqa: F403,F401
|
||||
|
||||
# General information about the project.
|
||||
project = u'ESP-Protocols'
|
||||
copyright = u'2016 - 2022, Espressif Systems (Shanghai) Co., Ltd'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
language = 'en'
|
@ -1,126 +0,0 @@
|
||||
ESP WebSocket Client
|
||||
====================
|
||||
|
||||
Overview
|
||||
--------
|
||||
The ESP WebSocket client is an implementation of `WebSocket protocol client <https://tools.ietf.org/html/rfc6455>`_ for {IDF_TARGET_NAME}
|
||||
|
||||
Features
|
||||
--------
|
||||
* Supports WebSocket over TCP, TLS with mbedtls
|
||||
* Easy to setup with URI
|
||||
* Multiple instances (Multiple clients in one application)
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
URI
|
||||
^^^
|
||||
|
||||
- Supports ``ws``, ``wss`` schemes
|
||||
- WebSocket samples:
|
||||
|
||||
- ``ws://echo.websocket.org``: WebSocket over TCP, default port 80
|
||||
- ``wss://echo.websocket.org``: WebSocket over SSL, default port 443
|
||||
|
||||
Minimal configurations:
|
||||
|
||||
.. code:: c
|
||||
|
||||
const esp_websocket_client_config_t ws_cfg = {
|
||||
.uri = "ws://echo.websocket.org",
|
||||
};
|
||||
|
||||
The WebSocket client supports the use of both path and query in the URI. Sample:
|
||||
|
||||
.. code:: c
|
||||
|
||||
const esp_websocket_client_config_t ws_cfg = {
|
||||
.uri = "ws://echo.websocket.org/connectionhandler?id=104",
|
||||
};
|
||||
|
||||
|
||||
If there are any options related to the URI in
|
||||
:cpp:type:`esp_websocket_client_config_t`, the option defined by the URI will be
|
||||
overridden. Sample:
|
||||
|
||||
.. code:: c
|
||||
|
||||
const esp_websocket_client_config_t ws_cfg = {
|
||||
.uri = "ws://echo.websocket.org:123",
|
||||
.port = 4567,
|
||||
};
|
||||
//WebSocket client will connect to websocket.org using port 4567
|
||||
|
||||
TLS
|
||||
^^^
|
||||
|
||||
Configuration:
|
||||
|
||||
.. code:: c
|
||||
|
||||
const esp_websocket_client_config_t ws_cfg = {
|
||||
.uri = "wss://echo.websocket.org",
|
||||
.cert_pem = (const char *)websocket_org_pem_start,
|
||||
};
|
||||
|
||||
.. note:: If you want to verify the server, then you need to provide a certificate in PEM format, and provide to ``cert_pem`` in :cpp:type:`websocket_client_config_t`. If no certficate is provided then the TLS connection will default to not requiring verification.
|
||||
|
||||
PEM certificate for this example could be extracted from an openssl `s_client` command connecting to websocket.org.
|
||||
In case a host operating system has `openssl` and `sed` packages installed, one could execute the following command to download and save the root or intermediate root certificate to a file (Note for Windows users: Both Linux like environment or Windows native packages may be used).
|
||||
```
|
||||
echo "" | openssl s_client -showcerts -connect websocket.org:443 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >websocket_org.pem
|
||||
```
|
||||
|
||||
This command will extract the second certificate in the chain and save it as a pem-file.
|
||||
|
||||
Subprotocol
|
||||
^^^^^^^^^^^
|
||||
|
||||
The subprotocol field in the config struct can be used to request a subprotocol
|
||||
|
||||
.. code:: c
|
||||
|
||||
const esp_websocket_client_config_t ws_cfg = {
|
||||
.uri = "ws://websocket.org",
|
||||
.subprotocol = "soap",
|
||||
};
|
||||
|
||||
.. note:: The client is indifferent to the subprotocol field in the server response and will accept the connection no matter what the server replies.
|
||||
|
||||
For more options on :cpp:type:`esp_websocket_client_config_t`, please refer to API reference below
|
||||
|
||||
Events
|
||||
------
|
||||
* `WEBSOCKET_EVENT_CONNECTED`: The client has successfully established a connection to the server. The client is now ready to send and receive data. Contains no event data.
|
||||
* `WEBSOCKET_EVENT_DISCONNECTED`: The client has aborted the connection due to the transport layer failing to read data, e.g. because the server is unavailable. Contains no event data.
|
||||
* `WEBSOCKET_EVENT_DATA`: The client has successfully received and parsed a WebSocket frame. The event data contains a pointer to the payload data, the length of the payload data as well as the opcode of the received frame. A message may be fragmented into multiple events if the length exceeds the buffer size. This event will also be posted for non-payload frames, e.g. pong or connection close frames.
|
||||
* `WEBSOCKET_EVENT_ERROR`: Not used in the current implementation of the client.
|
||||
|
||||
If the client handle is needed in the event handler it can be accessed through the pointer passed to the event handler:
|
||||
|
||||
.. code:: c
|
||||
|
||||
esp_websocket_client_handle_t client = (esp_websocket_client_handle_t)handler_args;
|
||||
|
||||
|
||||
Limitations and Known Issues
|
||||
----------------------------
|
||||
* The client is able to request the use of a subprotocol from the server during the handshake, but does not do any subprotocol related checks on the response from the server.
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
A simple WebSocket example that uses esp_websocket_client to establish a websocket connection and send/receive data with the `websocket.org <https://websocket.org>`_ server can be found here: :example:`example <../examples>`.
|
||||
|
||||
Sending Text Data
|
||||
^^^^^^^^^^^^^^^^^
|
||||
The WebSocket client supports sending data as a text data frame, which informs the application layer that the payload data is text data encoded as UTF-8. Example:
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
esp_websocket_client_send_text(client, data, len, portMAX_DELAY);
|
||||
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/esp_websocket_client.inc
|
@ -1,26 +0,0 @@
|
||||
build-docs --target esp32 --language en
|
||||
|
||||
cp -rf _build/en/esp32/html .
|
||||
rm -rf _build __pycache__
|
||||
|
||||
# Modifes some version and target fields of index.html
|
||||
echo "<script type="text/javascript">
|
||||
window.onload =(function() {
|
||||
var myAnchor = document.getElementById('version-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.setAttribute('type', 'text');
|
||||
mySpan.setAttribute('maxLength', '10');
|
||||
mySpan.value = 'latest';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
|
||||
var myAnchor = document.getElementById('target-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.setAttribute('type', 'text');
|
||||
mySpan.setAttribute('maxLength', '10');
|
||||
mySpan.value = 'all targets';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
|
||||
})();
|
||||
</script>" >> html/index.html
|
@ -1,75 +0,0 @@
|
||||
# This is Doxygen configuration file
|
||||
#
|
||||
# Doxygen provides over 260 configuration statements
|
||||
# To make this file easier to follow,
|
||||
# it contains only statements that are non-default
|
||||
#
|
||||
# NOTE:
|
||||
# It is recommended not to change defaults unless specifically required
|
||||
# Test any changes how they affect generated documentation
|
||||
# Make sure that correct warnings are generated to flag issues with documented code
|
||||
#
|
||||
# For the complete list of configuration statements see:
|
||||
# http://doxygen.nl/manual/config.html
|
||||
|
||||
|
||||
PROJECT_NAME = "ESP Protocols Programming Guide"
|
||||
|
||||
## The 'INPUT' statement below is used as input by script 'gen-df-input.py'
|
||||
## to automatically generate API reference list files heder_file.inc
|
||||
## These files are placed in '_inc' directory
|
||||
## and used to include in API reference documentation
|
||||
|
||||
INPUT = \
|
||||
$(PROJECT_PATH)/include/mdns.h
|
||||
|
||||
## Get warnings for functions that have no documentation for their parameters or return value
|
||||
##
|
||||
WARN_NO_PARAMDOC = YES
|
||||
|
||||
## Enable preprocessing and remove __attribute__(...) expressions from the INPUT files
|
||||
##
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = \
|
||||
$(ENV_DOXYGEN_DEFINES) \
|
||||
__DOXYGEN__=1 \
|
||||
__attribute__(x)= \
|
||||
_Static_assert()= \
|
||||
IDF_DEPRECATED(X)= \
|
||||
IRAM_ATTR= \
|
||||
configSUPPORT_DYNAMIC_ALLOCATION=1 \
|
||||
configSUPPORT_STATIC_ALLOCATION=1 \
|
||||
configQUEUE_REGISTRY_SIZE=1 \
|
||||
configUSE_RECURSIVE_MUTEXES=1 \
|
||||
configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS=1 \
|
||||
configNUM_THREAD_LOCAL_STORAGE_POINTERS=1 \
|
||||
configUSE_APPLICATION_TASK_TAG=1 \
|
||||
configTASKLIST_INCLUDE_COREID=1 \
|
||||
"ESP_EVENT_DECLARE_BASE(x)=extern esp_event_base_t x"
|
||||
|
||||
## Do not complain about not having dot
|
||||
##
|
||||
HAVE_DOT = NO
|
||||
|
||||
## Generate XML that is required for Breathe
|
||||
##
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = xml
|
||||
|
||||
GENERATE_HTML = NO
|
||||
HAVE_DOT = NO
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_MAN = YES
|
||||
GENERATE_RTF = NO
|
||||
|
||||
## Skip distracting progress messages
|
||||
##
|
||||
QUIET = YES
|
||||
|
||||
## Enable Section Tags for conditional documentation
|
||||
##
|
||||
ENABLED_SECTIONS += \
|
||||
DOC_EXCLUDE_HEADER_SECTION \ ## To conditionally remove doc sections from IDF source files without affecting documentation in upstream files.
|
||||
DOC_SINGLE_GROUP ## To conditionally remove groups from the documentation and create a 'flat' document without affecting documentation in upstream files.
|
@ -1,23 +0,0 @@
|
||||
# flake8: noqa
|
||||
from esp_docs.conf_docs import *
|
||||
|
||||
extensions += [
|
||||
'sphinx_copybutton',
|
||||
# Needed as a trigger for running doxygen
|
||||
'esp_docs.esp_extensions.dummy_build_system',
|
||||
'esp_docs.esp_extensions.run_doxygen',
|
||||
]
|
||||
|
||||
# link roles config
|
||||
github_repo = 'espressif/esp-protocols'
|
||||
|
||||
# context used by sphinx_idf_theme
|
||||
html_context['github_user'] = 'espressif'
|
||||
html_context['github_repo'] = 'esp-protocols'
|
||||
|
||||
# Extra options required by sphinx_idf_theme
|
||||
project_slug = 'esp-idf' # >=5.0
|
||||
versions_url = 'https://github.com/espressif/esp-protocols/docs/docs_versions.js'
|
||||
|
||||
idf_targets = ['esp32']
|
||||
languages = ['en', 'zh_CN']
|
@ -1,24 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
#
|
||||
# Uses ../conf_common.py for most non-language-specific settings.
|
||||
|
||||
# Importing conf_common adds all the non-language-specific
|
||||
# parts to this conf module
|
||||
|
||||
try:
|
||||
from conf_common import * # noqa: F403,F401
|
||||
except ImportError:
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('../'))
|
||||
from conf_common import * # noqa: F403,F401
|
||||
|
||||
# General information about the project.
|
||||
project = u'ESP-Protocols'
|
||||
copyright = u'2016 - 2022, Espressif Systems (Shanghai) Co., Ltd'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
language = 'en'
|
@ -1,203 +0,0 @@
|
||||
mDNS Service
|
||||
============
|
||||
`zh_CN:[中文] <https://espressif.github.io/esp-protocols/mdns/zh_CN/index.html>`_
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
mDNS is a multicast UDP service that is used to provide local network service and host discovery.
|
||||
|
||||
mDNS is installed by default on most operating systems or is available as separate package. On ``Mac OS`` it is installed by default and is called ``Bonjour``. Apple releases an installer for ``Windows`` that can be found `on Apple's support page <https://support.apple.com/downloads/bonjour%2520for%2520windows>`_. On ``Linux``, mDNS is provided by `avahi <https://github.com/lathiat/avahi>`_ and is usually installed by default.
|
||||
|
||||
mDNS Properties
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
* ``hostname``: the hostname that the device will respond to. If not set, the ``hostname`` will be read from the interface. Example: ``my-{IDF_TARGET_PATH_NAME}`` will resolve to ``my-{IDF_TARGET_PATH_NAME}.local``
|
||||
* ``default_instance``: friendly name for your device, like ``Jhon's {IDF_TARGET_NAME} Thing``. If not set, ``hostname`` will be used.
|
||||
|
||||
Example method to start mDNS for the STA interface and set ``hostname`` and ``default_instance``:
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
void start_mdns_service()
|
||||
{
|
||||
//initialize mDNS service
|
||||
esp_err_t err = mdns_init();
|
||||
if (err) {
|
||||
printf("MDNS Init failed: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
//set hostname
|
||||
mdns_hostname_set("my-{IDF_TARGET_PATH_NAME}");
|
||||
//set default instance
|
||||
mdns_instance_name_set("Jhon's {IDF_TARGET_NAME} Thing");
|
||||
}
|
||||
|
||||
mDNS Services
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
mDNS can advertise information about network services that your device offers. Each service is defined by a few properties.
|
||||
|
||||
* ``instance_name``: friendly name for your service, like ``Jhon's E{IDF_TARGET_NAME} Web Server``. If not defined, ``default_instance`` will be used.
|
||||
* ``service_type``: (required) service type, prepended with underscore. Some common types can be found `here <http://www.dns-sd.org/serviceTypes.html>`_.
|
||||
* ``proto``: (required) protocol that the service runs on, prepended with underscore. Example: ``_tcp`` or ``_udp``
|
||||
* ``port``: (required) network port that the service runs on
|
||||
* ``txt``: ``{var, val}`` array of strings, used to define properties for your service
|
||||
|
||||
Example method to add a few services and different properties::
|
||||
|
||||
void add_mdns_services()
|
||||
{
|
||||
//add our services
|
||||
mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0);
|
||||
mdns_service_add(NULL, "_arduino", "_tcp", 3232, NULL, 0);
|
||||
mdns_service_add(NULL, "_myservice", "_udp", 1234, NULL, 0);
|
||||
|
||||
//NOTE: services must be added before their properties can be set
|
||||
//use custom instance for the web server
|
||||
mdns_service_instance_name_set("_http", "_tcp", "Jhon's {IDF_TARGET_NAME} Web Server");
|
||||
|
||||
mdns_txt_item_t serviceTxtData[3] = {
|
||||
{"board","{{IDF_TARGET_PATH_NAME}}"},
|
||||
{"u","user"},
|
||||
{"p","password"}
|
||||
};
|
||||
//set txt data for service (will free and replace current data)
|
||||
mdns_service_txt_set("_http", "_tcp", serviceTxtData, 3);
|
||||
|
||||
//change service port
|
||||
mdns_service_port_set("_myservice", "_udp", 4321);
|
||||
}
|
||||
|
||||
mDNS Query
|
||||
^^^^^^^^^^
|
||||
|
||||
mDNS provides methods for browsing for services and resolving host's IP/IPv6 addresses.
|
||||
|
||||
Results for services are returned as a linked list of ``mdns_result_t`` objects.
|
||||
|
||||
Example method to resolve host IPs::
|
||||
|
||||
void resolve_mdns_host(const char * host_name)
|
||||
{
|
||||
printf("Query A: %s.local", host_name);
|
||||
|
||||
struct ip4_addr addr;
|
||||
addr.addr = 0;
|
||||
|
||||
esp_err_t err = mdns_query_a(host_name, 2000, &addr);
|
||||
if(err){
|
||||
if(err == ESP_ERR_NOT_FOUND){
|
||||
printf("Host was not found!");
|
||||
return;
|
||||
}
|
||||
printf("Query Failed");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(IPSTR, IP2STR(&addr));
|
||||
}
|
||||
|
||||
Example method to resolve local services::
|
||||
|
||||
static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
|
||||
static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
|
||||
|
||||
void mdns_print_results(mdns_result_t * results){
|
||||
mdns_result_t * r = results;
|
||||
mdns_ip_addr_t * a = NULL;
|
||||
int i = 1, t;
|
||||
while(r){
|
||||
printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]);
|
||||
if(r->instance_name){
|
||||
printf(" PTR : %s\n", r->instance_name);
|
||||
}
|
||||
if(r->hostname){
|
||||
printf(" SRV : %s.local:%u\n", r->hostname, r->port);
|
||||
}
|
||||
if(r->txt_count){
|
||||
printf(" TXT : [%u] ", r->txt_count);
|
||||
for(t=0; t<r->txt_count; t++){
|
||||
printf("%s=%s; ", r->txt[t].key, r->txt[t].value);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
a = r->addr;
|
||||
while(a){
|
||||
if(a->addr.type == IPADDR_TYPE_V6){
|
||||
printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
|
||||
} else {
|
||||
printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void find_mdns_service(const char * service_name, const char * proto)
|
||||
{
|
||||
ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto);
|
||||
|
||||
mdns_result_t * results = NULL;
|
||||
esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results);
|
||||
if(err){
|
||||
ESP_LOGE(TAG, "Query Failed");
|
||||
return;
|
||||
}
|
||||
if(!results){
|
||||
ESP_LOGW(TAG, "No results found!");
|
||||
return;
|
||||
}
|
||||
|
||||
mdns_print_results(results);
|
||||
mdns_query_results_free(results);
|
||||
}
|
||||
|
||||
Example of using the methods above::
|
||||
|
||||
void my_app_some_method(){
|
||||
//search for {IDF_TARGET_PATH_NAME}-mdns.local
|
||||
resolve_mdns_host("{IDF_TARGET_PATH_NAME}-mdns");
|
||||
|
||||
//search for HTTP servers
|
||||
find_mdns_service("_http", "_tcp");
|
||||
//or file servers
|
||||
find_mdns_service("_smb", "_tcp"); //windows sharing
|
||||
find_mdns_service("_afpovertcp", "_tcp"); //apple sharing
|
||||
find_mdns_service("_nfs", "_tcp"); //NFS server
|
||||
find_mdns_service("_ftp", "_tcp"); //FTP server
|
||||
//or networked printer
|
||||
find_mdns_service("_printer", "_tcp");
|
||||
find_mdns_service("_ipp", "_tcp");
|
||||
}
|
||||
|
||||
|
||||
Performance Optimization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Execution Speed
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
- mDNS creates a task with default low priority 1 ``CONFIG_MDNS_TASK_PRIORITY`` (If ``CONFIG_FREERTOS_UNICORE`` enabeled it pinned to CPU0 (``CONFIG_MDNS_TASK_AFFINITY``).
|
||||
Please check `Maximizing Execution Speed <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/performance/speed.html>`_ for more details.
|
||||
|
||||
Minimizing RAM Usage
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- mDNS creates a tasks with stack sizes configured by ``CONFIG_MDNS_TASK_STACK_SIZE``.
|
||||
Please check `Minimizing RAM Usage <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/performance/ram-usage.html>`_ for more details.
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
mDNS server/scanner example: :example:`<../examples>`.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/mdns.inc
|
@ -1,28 +0,0 @@
|
||||
build-docs --target esp32 --language en
|
||||
build-docs --target esp32 --language zh_CN
|
||||
|
||||
cp -rf _build/en/esp32/html html_en
|
||||
cp -rf _build/zh_CN/esp32/html html_zh_CN
|
||||
rm -rf _build __pycache__ tee
|
||||
|
||||
# Modifes some version and target fields of index.html
|
||||
echo "<script type="text/javascript">
|
||||
window.onload =(function() {
|
||||
var myAnchor = document.getElementById('version-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.setAttribute('type', 'text');
|
||||
mySpan.setAttribute('maxLength', '10');
|
||||
mySpan.value = 'latest';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
|
||||
var myAnchor = document.getElementById('target-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.setAttribute('type', 'text');
|
||||
mySpan.setAttribute('maxLength', '10');
|
||||
mySpan.value = 'all targets';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
|
||||
})();
|
||||
</script>" | tee -a html_en/index.html html_zh_CN/index.html > /dev/null
|
@ -1,27 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
#
|
||||
# Uses ../conf_common.py for most non-language-specific settings.
|
||||
|
||||
# Importing conf_common adds all the non-language-specific
|
||||
# parts to this conf module
|
||||
try:
|
||||
from conf_common import * # noqa: F403,F401
|
||||
except ImportError:
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
from conf_common import * # noqa: F403,F401
|
||||
|
||||
import datetime
|
||||
|
||||
current_year = datetime.datetime.now().year
|
||||
|
||||
# General information about the project.
|
||||
project = u'ESP-IDF 编程指南'
|
||||
copyright = u'2016 - {} 乐鑫信息科技(上海)股份有限公司'.format(current_year)
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
language = 'zh_CN'
|
@ -1,187 +0,0 @@
|
||||
mDNS 服务
|
||||
=========
|
||||
`en:[English] <https://espressif.github.io/esp-protocols/mdns/en/index.html>`_
|
||||
|
||||
概述
|
||||
----
|
||||
|
||||
mDNS 是一种组播 UDP 服务,用来提供本地网络服务和主机发现。
|
||||
|
||||
绝大多数的操作系统默认都会安装 mDNS 服务,或者提供单独的安装包。``Mac OS`` 默认会安装名为 ``Bonjour`` 的服务(该服务基于 mDNS),此外 Apple 还发布了适用于 Windows 系统的安装程序,可以在 `官方支持 <https://support.apple.com/downloads/bonjour%2520for%2520windows>`_ 找到。在 ``Linux`` 上,mDNS 服务由 `avahi <https://github.com/lathiat/avahi>`_ 提供,通常也会被默认安装。
|
||||
|
||||
mDNS 属性
|
||||
^^^^^^^^^
|
||||
|
||||
* ``hostname``:设备会去响应的主机名,如果没有设置,会根据设备的网络接口名定义 ``hostname`` 。例如,``my-{IDF_TARGET_PATH_NAME}`` 会被解析为 ``my-{IDF_TARGET_PATH_NAME}.local``。
|
||||
* ``default_instance``:默认实例名(即易记的设备名),例如 ``Jhon's {IDF_TARGET_NAME} Thing``。如果没有设置,将会使用 ``hostname``。
|
||||
|
||||
以下为 STA 接口启动 mDNS 服务并设置 ``hostname`` 和 ``default_instance`` 的示例方法:
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
void start_mdns_service()
|
||||
{
|
||||
// 初始化 mDNS 服务
|
||||
esp_err_t err = mdns_init();
|
||||
if (err) {
|
||||
printf("MDNS Init failed: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置 hostname
|
||||
mdns_hostname_set("my-{IDF_TARGET_PATH_NAME}");
|
||||
// 设置默认实例
|
||||
mdns_instance_name_set("Jhon's {IDF_TARGET_NAME} Thing");
|
||||
}
|
||||
|
||||
mDNS 服务
|
||||
^^^^^^^^^
|
||||
|
||||
mDNS 可以广播设备能够提供的网络服务的相关信息,每个服务会由以下属性构成。
|
||||
|
||||
* ``instance_name``:实例名(即易记的服务名),例如 ``Jhon's {IDF_TARGET_NAME} Web Server``。如果没有定义,会使用 ``default_instance``。
|
||||
* ``service_type``:(必需)服务类型,以下划线为前缀,`这里 <http://www.dns-sd.org/serviceTypes.html>`_ 列出了常见的类型。
|
||||
* ``proto``:(必需)服务运行所依赖的协议,以下划线为前缀,例如 ``_tcp`` 或者 ``_udp``。
|
||||
* ``port``:(必需)服务运行所用的端口号。
|
||||
* ``txt``:形如 ``{var, val}`` 的字符串数组,用于定义服务的属性。
|
||||
|
||||
添加一些服务和不同属性的示例方法::
|
||||
|
||||
void add_mdns_services()
|
||||
{
|
||||
// 添加服务
|
||||
mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0);
|
||||
mdns_service_add(NULL, "_arduino", "_tcp", 3232, NULL, 0);
|
||||
mdns_service_add(NULL, "_myservice", "_udp", 1234, NULL, 0);
|
||||
|
||||
// 注意:必须先添加服务,然后才能设置其属性
|
||||
// web 服务器使用自定义的实例名
|
||||
mdns_service_instance_name_set("_http", "_tcp", "Jhon's {IDF_TARGET_NAME} Web Server");
|
||||
|
||||
mdns_txt_item_t serviceTxtData[3] = {
|
||||
{"board","{IDF_TARGET_PATH_NAME}"},
|
||||
{"u","user"},
|
||||
{"p","password"}
|
||||
};
|
||||
// 设置服务的文本数据(会释放并替换当前数据)
|
||||
mdns_service_txt_set("_http", "_tcp", serviceTxtData, 3);
|
||||
|
||||
// 修改服务端口号
|
||||
mdns_service_port_set("_myservice", "_udp", 4321);
|
||||
}
|
||||
|
||||
mDNS 查询
|
||||
^^^^^^^^^
|
||||
|
||||
mDNS 提供查询服务和解析主机 IP/IPv6 地址的方法。
|
||||
|
||||
服务查询的结果会作为 ``mdns_result_t`` 类型对象的链表返回。
|
||||
|
||||
解析主机 IP 地址的示例方法::
|
||||
|
||||
void resolve_mdns_host(const char * host_name)
|
||||
{
|
||||
printf("Query A: %s.local", host_name);
|
||||
|
||||
struct ip4_addr addr;
|
||||
addr.addr = 0;
|
||||
|
||||
esp_err_t err = mdns_query_a(host_name, 2000, &addr);
|
||||
if(err){
|
||||
if(err == ESP_ERR_NOT_FOUND){
|
||||
printf("Host was not found!");
|
||||
return;
|
||||
}
|
||||
printf("Query Failed");
|
||||
return;
|
||||
}
|
||||
|
||||
printf(IPSTR, IP2STR(&addr));
|
||||
}
|
||||
|
||||
解析本地服务的示例方法::
|
||||
|
||||
static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
|
||||
static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
|
||||
|
||||
void mdns_print_results(mdns_result_t * results){
|
||||
mdns_result_t * r = results;
|
||||
mdns_ip_addr_t * a = NULL;
|
||||
int i = 1, t;
|
||||
while(r){
|
||||
printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]);
|
||||
if(r->instance_name){
|
||||
printf(" PTR : %s\n", r->instance_name);
|
||||
}
|
||||
if(r->hostname){
|
||||
printf(" SRV : %s.local:%u\n", r->hostname, r->port);
|
||||
}
|
||||
if(r->txt_count){
|
||||
printf(" TXT : [%u] ", r->txt_count);
|
||||
for(t=0; t<r->txt_count; t++){
|
||||
printf("%s=%s; ", r->txt[t].key, r->txt[t].value);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
a = r->addr;
|
||||
while(a){
|
||||
if(a->addr.type == IPADDR_TYPE_V6){
|
||||
printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
|
||||
} else {
|
||||
printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void find_mdns_service(const char * service_name, const char * proto)
|
||||
{
|
||||
ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto);
|
||||
|
||||
mdns_result_t * results = NULL;
|
||||
esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results);
|
||||
if(err){
|
||||
ESP_LOGE(TAG, "Query Failed");
|
||||
return;
|
||||
}
|
||||
if(!results){
|
||||
ESP_LOGW(TAG, "No results found!");
|
||||
return;
|
||||
}
|
||||
|
||||
mdns_print_results(results);
|
||||
mdns_query_results_free(results);
|
||||
}
|
||||
|
||||
使用上述方法的示例::
|
||||
|
||||
void my_app_some_method(){
|
||||
// 搜索 {IDF_TARGET_PATH_NAME}-mdns.local
|
||||
resolve_mdns_host("{IDF_TARGET_PATH_NAME}-mdns");
|
||||
|
||||
// 搜索 HTTP 服务器
|
||||
find_mdns_service("_http", "_tcp");
|
||||
// 或者搜索文件服务器
|
||||
find_mdns_service("_smb", "_tcp"); // Windows 系统的共享服务
|
||||
find_mdns_service("_afpovertcp", "_tcp"); // Apple AFP 文件共享服务
|
||||
find_mdns_service("_nfs", "_tcp"); // NFS 服务器
|
||||
find_mdns_service("_ftp", "_tcp"); // FTP 服务器
|
||||
// 或者网络打印机
|
||||
find_mdns_service("_printer", "_tcp");
|
||||
find_mdns_service("_ipp", "_tcp");
|
||||
}
|
||||
|
||||
应用示例
|
||||
--------
|
||||
|
||||
有关 mDNS 服务器和查询器的应用示例请参考 :example:`<../examples>`。
|
||||
|
||||
API 参考
|
||||
--------
|
||||
|
||||
.. include-build-file:: inc/mdns.inc
|
Reference in New Issue
Block a user