Compare commits

..

453 Commits

Author SHA1 Message Date
8fe2a3a661 Minor fixes here and there
1. mDNS: Added idf_component.yml
2. mDNS: Updated document generation paths
2. Websocket: Updated conf_common.py to use internal
3. Websocket: Updated CmakeList.txt to use internal
2022-06-03 17:18:57 +04:00
417591b99f Merge pull request #43 from gabsuren/mdns_migration_with_history
mdns: Initial version based on IDF 5.0
2022-06-03 12:57:35 +02:00
b6b20ad399 mDNS: Initial version based on IDF 5.0 2022-06-01 21:04:37 +04:00
8863ed944d docs: update redirected links
* Original commit: espressif/esp-idf@030cb77597
2022-05-27 17:44:25 +04:00
78001ec871 Examples: common source for GPIO range in Kconfigs defined
* Original commit: espressif/esp-idf@1a20b10fd3
2022-05-27 17:44:25 +04:00
4a52cf23f5 soc: moved kconfig options out of the target component.
Moved the following kconfig options out of the target component:
 * CONFIG_ESP*_DEFAULT_CPU_FREQ* -> esp_system
 * ESP*_REV_MIN -> esp_hw_support
 * ESP*_TIME_SYSCALL -> newlib
 * ESP*_RTC_* -> esp_hw_support

Where applicable these target specific konfig names were merged into
a single common config, e.g;
CONFIG_ESP*_DEFAULT_CPU_FREQ -> CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ


* Original commit: espressif/esp-idf@d2872095f9
2022-05-27 17:44:25 +04:00
00e7675913 examples: added ESP-NETIF L2 TAP example
* Original commit: espressif/esp-idf@fcdb0306d0
2022-05-27 17:44:25 +04:00
87c269911d cmake: fix issue with passing cxx_std option for GCC 11, a common workaround
* Original commit: espressif/esp-idf@ea0d2123c8
2022-05-27 17:44:25 +04:00
eb536a74a0 kconfig: Changed default values of bool configs
- Some bool configs were using default values true and false,
  instead of y and n.


* Original commit: espressif/esp-idf@25c5c214f3
2022-05-27 17:44:25 +04:00
b720d02fca examples: Fix implicit includes after legacy code removal
* Original commit: espressif/esp-idf@c941e29cf6
2022-05-27 17:44:25 +04:00
3e93ea9b76 esp_netif: Remove tcpip_adapter compatibility layer
* Original commit: espressif/esp-idf@795b7ed993
2022-05-27 17:44:25 +04:00
2c764b1b7a mdns: Fix copyright messages, update API descrition
* Impove docs and comments on custom netifs
* Make predef interfaces const, minor docs fixes


* Original commit: espressif/esp-idf@42ba8a8338
2022-05-27 17:44:25 +04:00
f836ae7f65 mdns: Add API to control custom network interfaces
* Original commit: espressif/esp-idf@b02468dc98
2022-05-27 17:44:25 +04:00
e9a1c26e0c CI/mdns: Reworked example test to be run repeatably
* Original commit: espressif/esp-idf@dd3cd52fd6
2022-05-27 17:44:25 +04:00
4b5f24f5b8 CI/mdns: Fix fuzzer build
* Original commit: espressif/esp-idf@98e9426b66
2022-05-27 17:44:25 +04:00
05675c7d63 CI/mdns: Extend example test for sockets, netifs
* Original commit: espressif/esp-idf@d1b809e6a1
2022-05-27 17:44:25 +04:00
30f37c0565 mdns: Add support for registering custom netif
* Original commit: espressif/esp-idf@bec42ff85d
2022-05-27 17:44:25 +04:00
ddc58e8220 mdns: Indicate interface using esp_netif in search results
* Original commit: espressif/esp-idf@f8495f1e86
2022-05-27 17:44:25 +04:00
fa951bf320 mdns: Use predefined interfaces to prepare for custom netifs
* Original commit: espressif/esp-idf@f90b3b798b
2022-05-27 17:44:25 +04:00
605d1fab73 mdns: Prepare for dynamic esp-netif support
* Original commit: espressif/esp-idf@f9892f77b8
2022-05-27 17:44:25 +04:00
58bf2186f7 esp_hw_support/esp_system: Re-evaluate header inclusions and include directories
This commit updates the visibility of various header files and cleans up
some unnecessary inclusions. Also, this commit removes certain header
include paths which were maintained for backward compatibility.


* Original commit: espressif/esp-idf@a9fda54d39
2022-05-27 17:44:24 +04:00
d39a4c744e mdns: Stabilization of mdns test app
* Original commit: espressif/esp-idf@93a902ba80
2022-05-27 17:44:24 +04:00
ec491ec536 system: move kconfig options out of target component
Moved the following kconfig options out of the target component:
 * ESP32_X_BROWNOUT_* -> esp_system
 * ESP32_X_DEBUG_OCDAWARE -> esp_system
 * APP_NO_BLOBS -> build type (main kconfig)


* Original commit: espressif/esp-idf@bb88338118
2022-05-27 17:44:24 +04:00
defdfd59b6 G0: target component (components/esp32*) doesn't depend on driver anymore
* Original commit: espressif/esp-idf@2571aaf3c9
2022-05-27 17:44:24 +04:00
7f42c31252 ci/mdsn: Fix example test on ethernet runners
* Ethernet kit uses GPIO0 for ref-clock, so the test button hits
constantly
* Add a freeRTOS delay when checking result on assync queries


* Original commit: espressif/esp-idf@afe7ab3b2c
2022-05-27 17:44:24 +04:00
94ae672041 mdns: Update to drop our own packet if bounced back
* Original commit: espressif/esp-idf@b5149e3ee7
2022-05-27 17:44:24 +04:00
e5a3a3df1d mdns: Fix potential read behind parsed packet
* Original commit: espressif/esp-idf@51a5de2525
2022-05-27 17:44:24 +04:00
7710ea9a11 mdns: Fix memleak when adding delegated host
* Original commit: espressif/esp-idf@9cbdb8767b
2022-05-27 17:44:24 +04:00
034c55e18a mdns: Fix null-service issue when parsing packets
Closes https://github.com/espressif/esp-idf/issues/8307


* Original commit: espressif/esp-idf@a57be7b7d1
2022-05-27 17:44:24 +04:00
ec03fec3d3 mdns: Update fuzzer test (add delegation, check memory)
* Add new config with no services
* Add new test packets and more queries
* Allocate packet to check for mem issues


* Original commit: espressif/esp-idf@2c1007156e
2022-05-27 17:44:24 +04:00
5909e9e54c mdns: Remove legacy esp_event API
* Original commit: espressif/esp-idf@e46aa515bd
2022-05-27 17:44:24 +04:00
82e2a5dcc1 mdns: added missing includes
* Original commit: espressif/esp-idf@28d09c7dbe
2022-05-27 17:44:24 +04:00
48e4d4035c mdns: Clear notification value in mdns_hostname_set
Merges https://github.com/espressif/esp-idf/pull/8284


* Original commit: espressif/esp-idf@83a4ddbd25
2022-05-27 17:44:24 +04:00
ba3fa24a96 esp_eth: Update esp32's EMAC API to decouple driver and vendor config
* Original commit: espressif/esp-idf@8da2e4088c
2022-05-27 17:44:24 +04:00
869f5b75af esp_eth: Make EMAC DMA burst size configurable
Merges https://github.com/espressif/esp-idf/pull/7874
Closes  https://github.com/espressif/esp-idf/issues/7380


* Original commit: espressif/esp-idf@2553fb5845
2022-05-27 17:44:24 +04:00
ac6dcb6830 esp_timer: remove legacy ESP32 FRC timer implementation.
* Original commit: espressif/esp-idf@edb76f14d6
2022-05-27 17:44:24 +04:00
085dbd8c4e freertos: Remove legacy data types
This commit removes the usage of all legacy FreeRTOS data types that
are exposed via configENABLE_BACKWARD_COMPATIBILITY. Legacy types can
still be used by enabling CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY.


* Original commit: espressif/esp-idf@57fd78f5ba
2022-05-27 17:44:24 +04:00
f78e8cfce8 Tools: Custom baud-rate setup is not possible for IDF Monitor from menuconfig anymore
IDF Monitor follows the console baud rate by default. Other baud rate
can be set from command line by "idf.py monitor -B <baud>" or through
environment variables. Run "idf.py monitor --help" for more information.


* Original commit: espressif/esp-idf@36a4011ff8
2022-05-27 17:44:24 +04:00
6cdf5ee074 mdns: Use memcpy() for copy to support non-text TXTs
* Original commit: espressif/esp-idf@6aefe9c185
2022-05-27 17:44:24 +04:00
fcb5515f1e mdns: Support for null-value TXT records
Closes https://github.com/espressif/esp-idf/issues/8267


* Original commit: espressif/esp-idf@23c2db406d
2022-05-27 17:44:24 +04:00
9fdbe5f130 mdns: Fix alloc issue if TXT has empty value
* Original commit: espressif/esp-idf@205f6ba854
2022-05-27 17:44:24 +04:00
20e6e9e7fe mdns: Fix random crash when defalt service instance queried
Merges https://github.com/espressif/esp-idf/pull/8248


* Original commit: espressif/esp-idf@f46dffca62
2022-05-27 17:44:24 +04:00
3c5b13ea0d ci/mdns: Run mdns test on ethernet runners
* Original commit: espressif/esp-idf@96616b6056
2022-05-27 17:44:24 +04:00
c588263b45 mdns: Fix minor memory leaks when creating services
* Original commit: espressif/esp-idf@fad62cc1ed
2022-05-27 17:44:24 +04:00
6258edf23b Fix mDNS memory leak
* Original commit: espressif/esp-idf@119b4a9dd1
2022-05-27 17:44:24 +04:00
c8b0d5ea9d Fix mDNS memory leak
* Original commit: espressif/esp-idf@f5ffd53aeb
2022-05-27 17:44:24 +04:00
5252b1d801 mdns: Use multi/uni-cast types in API
* Original commit: espressif/esp-idf@125c312552
2022-05-27 17:44:24 +04:00
4e11cc86fe mdns: Allow for unicast PTR queries
Adresses https://github.com/espressif/esp-idf/issues/7932


* Original commit: espressif/esp-idf@7eeeb01ea7
2022-05-27 17:44:24 +04:00
7af91ec490 mdns: Fix potential null deref for ANY query type
* Original commit: espressif/esp-idf@99dd8eedb1
2022-05-27 17:44:24 +04:00
01256d3e34 mdns: Make fuzzer layers compatible with llvm>=6
* Original commit: espressif/esp-idf@1882cbe44e
2022-05-27 17:44:24 +04:00
5a2d4eab6d mdns: Fix copyright
* Original commit: espressif/esp-idf@c83678f64f
2022-05-27 17:44:24 +04:00
9de3f534e2 Add mDNS miss comment
* Original commit: espressif/esp-idf@08e081340d
2022-05-27 17:44:24 +04:00
bcabc8ea16 freertos: remove FREERTOS_ASSERT option
Freertos asserts are now configured the same way as all other asserts in IDF,
i.e. by configuring COMPILER_OPTIMIZATION_ASSERTION_LEVEL.


* Original commit: espressif/esp-idf@7255497146
2022-05-27 17:44:24 +04:00
dfb27b39cc mdns: Minor err print fix in socket-networking layer
* Original commit: espressif/esp-idf@f1b8f5c102
2022-05-27 17:44:24 +04:00
076c095aec unified errno format
* Original commit: espressif/esp-idf@87506f46e2
2022-05-27 17:44:24 +04:00
7dd0bc1fff mdns: always send A/AAAA records in announcements
* Original commit: espressif/esp-idf@456f80b754
2022-05-27 17:44:24 +04:00
7e82a7cef7 mdns: filter instance name for ANY queries
The instance name in ANY quries was ignored. The MR fixes the issue.


* Original commit: espressif/esp-idf@5d0c47303d
2022-05-27 17:44:24 +04:00
ae381b779f mdns: Fix potential null deref reported by fuzzer test
* Original commit: espressif/esp-idf@cb5653fd94
2022-05-27 17:44:24 +04:00
d0f4e68c7a mdns: Unbreak test app cauased by async API change
Regression from 81d496ace9080fcd97df3cc7e9ce279531d67a48


* Original commit: espressif/esp-idf@c0d08faf91
2022-05-27 17:44:24 +04:00
941dc5c42f mdns: Minor fix of API description and API usage
* Original commit: espressif/esp-idf@c297301ecc
2022-05-27 17:44:24 +04:00
525c64915e Added results count to MDNS
* Original commit: espressif/esp-idf@f391d610e8
2022-05-27 17:44:24 +04:00
f0839d909b mdns: fix mdns server instance mismatch
* Original commit: espressif/esp-idf@6173dd7809
2022-05-27 17:44:24 +04:00
69902ea8e1 mdns: support multiple instance for mdns service txt set
* Original commit: espressif/esp-idf@50f6302c5d
2022-05-27 17:44:24 +04:00
d5001e894f mdns: added test app
Closes IDF-4132


* Original commit: espressif/esp-idf@e0d5fca390
2022-05-27 17:44:24 +04:00
145a8d2291 esp_eth: rework KSZ80xx implementation and add more KSZ80xx PHYs
* add support for KSZ8001, KSZ8021, KSZ8031, KSZ8051 and KSZ8061
* remove duplicate code
* simplify architecture to make the code base extensible (for future work)


* Original commit: espressif/esp-idf@3fb83f2866
2022-05-27 17:44:24 +04:00
d0bbe880b6 mdns: fix wrong PTR record count
* Original commit: espressif/esp-idf@5d3f8157e0
2022-05-27 17:44:24 +04:00
4a9d55edf7 Build & config: Remove leftover files from the unsupported "make" build system
* Original commit: espressif/esp-idf@766aa57084
2022-05-27 17:44:24 +04:00
be2a924674 Build & config: Remove the "make" build system
The "make" build system was deprecated in v4.0 in favor of idf.py
(cmake). The remaining support is removed in v5.0.


* Original commit: espressif/esp-idf@9c1d4f5b54
2022-05-27 17:44:24 +04:00
76fcd4128a freertos: update freertos folder structure to match upstream
The following changes have been made:
1. All FreeRTOS kernel source files are now placed in the
   freertos/FreeRTOS-Kernel folder to match with the upstream folder structure.
2. All kernel include files are now placed in freertos/FreeRTOS-Kernel/include.
3. All port files are now placed in freertos/FreeRTOS-Kernel/portable.
4. All additions/customizations are placed in freertos/esp_additions.
5. All other miscellaneous files (README, License files etc.) are moved to
   freertos/FreeRTOS-Kernel folder to match with the upstream.
6. Updated esp-cryptoauthlib to latest commit to resolve FreeRTOS
   include dependencies.

Signed-off-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>


* Original commit: espressif/esp-idf@4846222102
2022-05-27 17:44:24 +04:00
fd8499c874 mdns: support service subtype
* Closes https://github.com/espressif/esp-idf/issues/5508


* Original commit: espressif/esp-idf@e7e8610f56
2022-05-27 17:44:24 +04:00
38b4fe2353 mdns: Fix parsing non-standard queries
Fix for packets containing unexpected domains, such as openthread.thread.home.arpa.
If we find this packet we set the name entry as invalid, but continue with parsing as the packet might contain related queries for us.

Closes https://github.com/espressif/esp-idf/issues/7694


* Original commit: espressif/esp-idf@d16f9bade5
2022-05-27 17:44:24 +04:00
eb7eeb58d3 [examples]: removed hyphens
Replaced hyphens with underscores in examples
project definition for all examples which had
hyphens in their project name. dpp-enrollee is
an exceptions because the name matches the
project directory name while the project
directory also contains hyphens.


* Original commit: espressif/esp-idf@81e9266204
2022-05-27 17:44:24 +04:00
b26606252f mdns: allow mutiple instances with same service type
* Original commit: espressif/esp-idf@b7a99f4658
2022-05-27 17:44:24 +04:00
5e087d82d6 mdns: Update copyright header
* Original commit: espressif/esp-idf@2a2b95b9c2
2022-05-27 17:44:24 +04:00
91a3d95f96 mdns: Fix potential null dereference identified by fuzzer tests
* Original commit: espressif/esp-idf@e7dabb14f7
2022-05-27 17:44:24 +04:00
6d6dd2b75e components/bt: move config BT_RESERVE_DRAM from bluedroid to ESP32 controller
* Original commit: espressif/esp-idf@b310c062cd
2022-05-27 17:44:24 +04:00
0611b0cb67 Eth_examples: added support of ESP32-S3 chip
Defined SPI modules default GPIO values for ESP32-S3

SPI bus needs to be initialized with SPI_DMA_CH_AUTO option


* Original commit: espressif/esp-idf@35454b2bf7
2022-05-27 17:44:24 +04:00
cf6ed1cc53 esp_eth: add support for multiple Ethernets modules at a time
Ethernet driver events properly bounded with ESP NETIF actions to support multiple Ethernet modules used at a time.

Components using Ethernet updated to conform with new API.

Closes https://github.com/espressif/esp-idf/issues/7318


* Original commit: espressif/esp-idf@ef30384902
2022-05-27 17:44:24 +04:00
52306e914f mdns: add notification callback for async APIs
* Original commit: espressif/esp-idf@986603cf07
2022-05-27 17:44:24 +04:00
d37ab6dd25 mdns: add more mdns result attributes
* Original commit: espressif/esp-idf@76ec76c12c
2022-05-27 17:44:24 +04:00
05dcd8f0ee examples/protocols: fix compilation when CONFIG_EXAMPLE_USE_OPENETH=y
The code checked CONFIG_ETH_USE_SPI_ETHERNET (which is usually set),
but CONFIG_EXAMPLE_ETH_SPI_xxx_GPIO options are only defined if
CONFIG_EXAMPLE_USE_SPI_ETHERNET is set. Fix the ifdef accordingly.
Regression from abc79de6.


* Original commit: espressif/esp-idf@ece73a3e55
2022-05-27 17:44:24 +04:00
5c55ea6e02 mdns: Add host test using linux target
* Original commit: espressif/esp-idf@fc7e2d9e90
2022-05-27 17:44:24 +04:00
0c71c7bfe1 mdns: Implement mdns_networking using BSD sockets
And use only if configured. By default we still use lwip raw (low-level) API


* Original commit: espressif/esp-idf@73dfe84bf2
2022-05-27 17:44:24 +04:00
4c368c0090 mdns: fix crash when adding services without hostname set
* Original commit: espressif/esp-idf@5e98772eaf
2022-05-27 17:44:24 +04:00
c2abeff476 examples: Update Ethernet examples to use new PHY LAN87xx init function
Ethernet examples device usage and Kconfig options synchronized


* Original commit: espressif/esp-idf@4e77430107
2022-05-27 17:44:24 +04:00
6a92d3253f CI: mdns example test: start responder after valid IP
to clean up the test and not to pollute the network unnecessarily.
Also keeps sending the delegated query until a response found


* Original commit: espressif/esp-idf@042fa1831e
2022-05-27 17:44:24 +04:00
af2275341e mdns: Fix fuzzer IDF-mock layer
Removed lwip dependencies
Simplified the mocks for esp32 and esp-netif


* Original commit: espressif/esp-idf@619235c2ee
2022-05-27 17:44:24 +04:00
b0957e70fd mdns: Clean the main mdns module from lwip dependencies
* Reduced number of include paths
* Abstract the internals of mdns packet (specifics defined in
mdns_networking.c)
* Use ESP_IP addresses instead of lwip addresses


* Original commit: espressif/esp-idf@54e329444a
2022-05-27 17:44:24 +04:00
47c7266103 mdns: Add asynchronous query API
Closes https://github.com/espressif/esp-idf/issues/7090


* Original commit: espressif/esp-idf@d81482d699
2022-05-27 17:44:24 +04:00
40da0d29be mdns: Fix crashes reported by the fuzzer tests
* Original commit: espressif/esp-idf@4a2e72677c
2022-05-27 17:44:24 +04:00
5f6b6f9273 mdns/fuzzer: Fix non-instrumentation test to reproduce fuzzer issues
Regression from 2893d7e21b skipped reading the packet causing issues when locally reproducing crashed found by the fuzzer


* Original commit: espressif/esp-idf@dae803335e
2022-05-27 17:44:24 +04:00
8a120829e2 mdns: return ESP_OK rather than ERR_OK in API functions
* Original commit: espressif/esp-idf@2386113972
2022-05-27 17:44:24 +04:00
46f28a8011 mdns: fix memory leak in mdns_free when adding delegated hostnames
* Original commit: espressif/esp-idf@0baee93211
2022-05-27 17:44:24 +04:00
5a81eaea3f mdns: Support for One-Shot mDNS queries
* Original commit: espressif/esp-idf@f167238fac
2022-05-27 17:44:24 +04:00
2ddaee2b6e mdns: allow explicit txt value length
* Original commit: espressif/esp-idf@b4e0088b68
2022-05-27 17:44:24 +04:00
73b1763029 example: set example wifi scan method to all channel:
in CI example test we could have runners with same SSID in the same lab.
Use scan on all channel will let DUT connect to the AP with best RSSI.


* Original commit: espressif/esp-idf@97a09e51ce
2022-05-27 17:44:24 +04:00
27fc285000 mdns: Fix crashes reported by the fuzzer
* Original commit: espressif/esp-idf@79ba738626
2022-05-27 17:44:24 +04:00
93e6efedc7 mdns: Minor correction of the test code
* Original commit: espressif/esp-idf@7d76245173
2022-05-27 17:44:24 +04:00
bc4cda8ea7 mdns: Fix fuzzer from miss-interpreting adding services as timeouts
* Original commit: espressif/esp-idf@14099fe15e
2022-05-27 17:44:24 +04:00
8a8d58d4dc mdns: fix test script delayed response
* Original commit: espressif/esp-idf@a4f263948c
2022-05-27 17:44:24 +04:00
402baebfee mdns: fix wrong SRV/PTR record handling
* Original commit: espressif/esp-idf@e6135552d2
2022-05-27 17:44:24 +04:00
9fa25ef3b6 mdns: fix wrong service hostname after mangling
* Original commit: espressif/esp-idf@439b31d065
2022-05-27 17:44:24 +04:00
121b525108 mdns: fix empty address change announce packets
* Original commit: espressif/esp-idf@7bbb72d865
2022-05-27 17:44:24 +04:00
418fb60dd9 mdns: fix mdns probe/reply behavior
* send correct hostnames when probing.
* add test for mdns host delegation.


* Original commit: espressif/esp-idf@d2a5d25984
2022-05-27 17:44:24 +04:00
4049b3b5ed mdns: make delegate host address a list
Also adds unit test and doc string for new apis.


* Original commit: espressif/esp-idf@2d34352f3d
2022-05-27 17:44:24 +04:00
c8821199a2 mdns: add remove delegate host api
* Original commit: espressif/esp-idf@2174693096
2022-05-27 17:44:24 +04:00
1eb5df9780 mdns: add mdns delegation
This allows publishing mdns services for other devices.


* Original commit: espressif/esp-idf@401ff56cc1
2022-05-27 17:44:24 +04:00
b62b4b3e25 mdns: fix memory free issue when repeating the query in reply
The repeated query will be copied in the next event loop while the
memory is freed instantly. Delay the free to fix this issue.


* Original commit: espressif/esp-idf@5f244c86f2
2022-05-27 17:44:24 +04:00
4d8aec1ad3 mdns: Fix of crash when wifi interface get deleted and mdns receives the packets
Closes https://github.com/espressif/esp-idf/issues/6973


* Original commit: espressif/esp-idf@03de74a728
2022-05-27 17:44:24 +04:00
6d649102ab Docs: Added README.md for lwip fuzzer tests
Closes IDFCI-540


* Original commit: espressif/esp-idf@53c18a85db
2022-05-27 17:44:24 +04:00
3ad559bf3f Split example_tests with Example_WIFI tag group into Example_OTA and Example_Protocols
* Original commit: espressif/esp-idf@0a395134d4
2022-05-27 17:44:24 +04:00
ab3fa69b8f mdns: Fixed the ip header TTL to be correctly set to 255
Defined in https://tools.ietf.org/html/rfc6762#section-11: All Multicast DNS responses (including responses sent via unicast)
   SHOULD be sent with IP TTL set to 255


* Original commit: espressif/esp-idf@5cce919cbe
2022-05-27 17:44:24 +04:00
c3a5826d60 mdns: Fix parsing answers with questions when instance name not set
mdns resolver didn't correctly resolved queries when host name wasn't
assigned. Fixed by allowing processing also if some answer present
(non-strict mode)

Closes https://github.com/espressif/esp-idf/issues/6598


* Original commit: espressif/esp-idf@34049454df
2022-05-27 17:44:24 +04:00
cbcbe4ffd7 mdns: Fix the resolver to correctly parse it's own non-strict answers
The resolver was able to respond correctly, but would also resolve its
own queries and cause issues with BCT 1.5.2, specifically
* MULTIPLE QUESTIONS - DUPLICATE SUPPRESSION
* MULTIPLE QUESTIONS - DISTRIBUTED DUPLICATE SUPPRESSION
tests failed.


* Original commit: espressif/esp-idf@b649603a0d
2022-05-27 17:44:23 +04:00
adc34309dc mdns: Add MDNS_STRICT_MODE config option
Strict mode was hardcoded in private header file, but it's useful for
users to enable/disable it depending on the mdns library they are using.
e.g. Avahi might not resolve the non-strict answers.


* Original commit: espressif/esp-idf@0eee31546d
2022-05-27 17:44:23 +04:00
7a8329cb5c Bugfix: Connect example to add scan mode config
Closes https://github.com/espressif/esp-idf/issues/6595


* Original commit: espressif/esp-idf@3373eff989
2022-05-27 17:44:23 +04:00
c30617d872 freertos: common config header
* Original commit: espressif/esp-idf@39cf818838
2022-05-27 17:44:23 +04:00
1e5eeb16ec mdns: Removed freeRTOS dependancies from fuzzer tests
* Original commit: espressif/esp-idf@55716945a9
2022-05-27 17:44:23 +04:00
22c7c0a195 mDNS: Updated APIs description and shows the warning when hostname contains domain name during the query
Closes https://github.com/espressif/esp-idf/issues/6590


* Original commit: espressif/esp-idf@9f8d2b944d
2022-05-27 17:44:23 +04:00
eda5d72acf examples: Strip IPv6 function in example and use sockaddr_storage to replace sockaddr_in6
* Original commit: espressif/esp-idf@821eea45b3
2022-05-27 17:44:23 +04:00
1623c0e729 components: Use CONFIG_LWIP_IPV6 to strip IPv6 function in components
* Original commit: espressif/esp-idf@da58235a0e
2022-05-27 17:44:23 +04:00
b114ed69de mdns: add bound check when setting interface as duplicate
Closes IDF-2787

Partially addresses https://github.com/espressif/esp-idf/issues/6440


* Original commit: espressif/esp-idf@2b9d2c06f5
2022-05-27 17:44:23 +04:00
49a00c2455 style: format python files with isort and double-quote-string-fixer
* Original commit: espressif/esp-idf@0146f258d7
2022-05-27 17:44:23 +04:00
dec1d7dcf8 esp_wifi: Modify ESP_IF_WIFI_STA to WIFI_IF_STA
* Original commit: espressif/esp-idf@b8a8fe3f54
2022-05-27 17:44:23 +04:00
2ffd22382d mDNS: Fix of text length calculation when detecting a collision
* Original commit: espressif/esp-idf@be0ae1ebbb
2022-05-27 17:44:23 +04:00
487287157d example: We should not check the return value of esp_wifi_connect() in any case
* Original commit: espressif/esp-idf@c260c223e9
2022-05-27 17:44:23 +04:00
1fe901f70f global: fix sign-compare warnings
* Original commit: espressif/esp-idf@753a929525
2022-05-27 17:44:23 +04:00
2cf9fd8891 lwip: Moved default SNTP API to esp_sntp.h
and make sntp.h in port folders of lwip component obsoleted


* Original commit: espressif/esp-idf@76f6dd6214
2022-05-27 17:44:23 +04:00
89439e0a9b mdns: Allow resolve its own non-strict answers
the mDNS responder should not repeat questions when replying, however resolvers
must ignore these questions field if they are present. esp-idf mDNS
library does include questions in answering packets (thus not strictly
following the RFC6762) so the resolver did not correctly resolved
another instance host name.

Closes https://github.com/espressif/esp-idf/issues/6190


* Original commit: espressif/esp-idf@0693e172de
2022-05-27 17:44:23 +04:00
becd5d0266 mDNS: Fix of collision detection during txt length calculation
Closes https://github.com/espressif/esp-idf/issues/6114


* Original commit: espressif/esp-idf@f33772c960
2022-05-27 17:44:23 +04:00
0d7a30944e esp32c3: Apply one-liner/small changes for ESP32-C3
* Original commit: espressif/esp-idf@5228d9f9ce
2022-05-27 17:44:23 +04:00
e2653e7fb0 eth: hide spi configuration when using internal emac
* Original commit: espressif/esp-idf@8d0a0537cc
2022-05-27 17:44:23 +04:00
df6a208f45 test: remove fake binary size check in example test:
the binary size check in example test was removed long time ago. Now we
have updated ttfw_idf to raise exception when performance standard is
not found. These fake performance check will be regarded as error.
Remove them now.


* Original commit: espressif/esp-idf@a908174c06
2022-05-27 17:44:23 +04:00
1fdffbbbab test: fix several test build error
* Original commit: espressif/esp-idf@b7ecccd901
2022-05-27 17:44:23 +04:00
d5566971fb eth: support W5500 in network examples
* Original commit: espressif/esp-idf@aea901f014
2022-05-27 17:44:23 +04:00
988d120902 freertos: Add RISC-V port
Changes come from internal branch commit a6723fc


* Original commit: espressif/esp-idf@87e13baaf1
2022-05-27 17:44:23 +04:00
fd47df3e30 mdns: Fix wrong mdns source address if lwIP IPv6 zones disabled
The struct definition of ip6_addr_t in lwip and esp_ip6_addr_t
differs since zone could be possibly disabled in lwip. Using memcpy to copy the
address will cause wrong source address. Copy the entries manually
instead.

Merges https://github.com/espressif/esp-idf/pull/6055


* Original commit: espressif/esp-idf@7ac97616c1
2022-05-27 17:44:23 +04:00
2cb3a6e35e Whitespace: Automated whitespace fixes (large commit)
Apply the pre-commit hook whitespace fixes to all files in the repo.

(Line endings, blank lines at end of file, trailing whitespace)


* Original commit: espressif/esp-idf@66fb5a29bb
2022-05-27 17:44:23 +04:00
ccd48bc9a9 lwip: Added description to Kconfig option on IPv6 SLAAC
Closes https://github.com/espressif/esp-idf/issues/6076
Merges https://github.com/espressif/esp-idf/pull/6078


* Original commit: espressif/esp-idf@9207c6ca8e
2022-05-27 17:44:23 +04:00
825652f3e1 test_compile_fuzzers: Fix include paths for host build
Regression in 988be6946681b592e3e51bb652b91bce54d7ba34, need to add
esp_hw_support component include dir here.


* Original commit: espressif/esp-idf@98a0cc783f
2022-05-27 17:44:23 +04:00
fc53888115 CI: Add a test to pre-check fuzzer tests compilation before weekly run
* Original commit: espressif/esp-idf@637f5c0a68
2022-05-27 17:44:23 +04:00
7635c0479b soc: descriptive part occupy whole component
* Original commit: espressif/esp-idf@79887fdc6c
2022-05-27 17:44:23 +04:00
d5fe42bffb Coredump config option rename throughout IDF
* Original commit: espressif/esp-idf@20af94ff53
2022-05-27 17:44:23 +04:00
e0bc60a586 mdns, dns, dhcp, dhcps: update fuzzer test to work in CI
Closes: IDF-1861 and IDF-1990


* Original commit: espressif/esp-idf@a43c06a592
2022-05-27 17:44:23 +04:00
9772e49b26 cmock: added cmock as component
* changing dependencies from unity->cmock
* added component.mk and Makefile.projbuild
* ignore test dir in gen_esp_err_to_name.py
* added some brief introduction of CMock in IDF


* Original commit: espressif/esp-idf@20c068ef3b
2022-05-27 17:44:23 +04:00
110f1f652d mdns test: Add test to resolve esp32 hostname with DiG
* Original commit: espressif/esp-idf@81e89476fe
2022-05-27 17:44:23 +04:00
ed77d65a82 examples: Common connect component: Unregister shutdown handler on disconnection
To be able to connect smoothly after disconnecting, we have to unregister all handlers including shutdown handler on disconnection


* Original commit: espressif/esp-idf@52a7721bf7
2022-05-27 17:44:23 +04:00
6021a88657 mdns: Support queries in responses in mDNS non-strict mode
By default adds original queries to responses in order to be resolved by some resolvers, such as lwIP mdns library. This functionality however is discouraged by the RFC6762, so it could be disabled in menuconfig if MDNS_STRICT_MODE configured

Closes https://github.com/espressif/esp-idf/issues/5521


* Original commit: espressif/esp-idf@bcfa36db8f
2022-05-27 17:44:23 +04:00
78f71ecdf6 mdns: Fix include query ID in reponses
Closes https://github.com/espressif/esp-idf/issues/5574


* Original commit: espressif/esp-idf@f62e321d87
2022-05-27 17:44:23 +04:00
07f57523c8 examples: common connect to also support no connection flow if no inteface chosen
This is useful for testing if there's no need for external network and connection


* Original commit: espressif/esp-idf@085d2b8d25
2022-05-27 17:44:23 +04:00
ad67a23097 vfs: support vfs uart set line endings with specified uart number
* Original commit: espressif/esp-idf@8e00522cd7
2022-05-27 17:44:23 +04:00
078abd8161 esp_rom: extract common GPIO apis into esp_rom_gpio.h
* Original commit: espressif/esp-idf@a4d0033c03
2022-05-27 17:44:23 +04:00
f1f6c5de05 examples: common connect: fix build error if ipv6 disabled
Declaration of local variable esp_ip6_addr_t ip6[]; was active even if IPV6 disabled in sdkconfig. Introduced in 62e39adff8db0605875fe7103c8919fbfe229f20


* Original commit: espressif/esp-idf@5c6bca69a5
2022-05-27 17:44:23 +04:00
12fb6d8e15 protocol_examples_common: keep buffering enabled on stdout
- Newlib uses significantly more stack space when printing to an unbuffered stream
- For examples tests, disabling buffering on stdout is not really required

This issue was found during one of the OTA example test failure, root cause
being stack overflow in `esp_event` task.


* Original commit: espressif/esp-idf@7925ba245d
2022-05-27 17:44:23 +04:00
2258d5bcef mdns-example: fail gracefully if mdns response not received within timeout
If mdns answer hasn't been received within timeout, Value error would be raised, but the mdns-server-thread would still run, blocking CI jobs. Fixed by moving the raise statement within try-finally block


* Original commit: espressif/esp-idf@3758177bf8
2022-05-27 17:44:23 +04:00
54f5c6f29c examples: common connect component to use both interfaces at once
* Original commit: espressif/esp-idf@06711c7c36
2022-05-27 17:44:23 +04:00
3319844745 mdns: Allow config mDNS task stack size
Signed-off-by: Axel Lin <axel.lin@gmail.com>

Merges https://github.com/espressif/esp-idf/pull/5216


* Original commit: espressif/esp-idf@cf7e48c779
2022-05-27 17:44:23 +04:00
ac70c9aba8 mdns: Remove mbedtls dependency
mdns does not use mbedtls, so remove mbedtls dependency.

Signed-off-by: Axel Lin <axel.lin@gmail.com>


* Original commit: espressif/esp-idf@f4a4549a34
2022-05-27 17:44:23 +04:00
123ae8db62 examples: add socket stdin utils to common connect component
* Original commit: espressif/esp-idf@a5a750ba48
2022-05-27 17:44:23 +04:00
e24cc7d1ae common_connect: add support for getting multiple IPv6 addresses
* Original commit: espressif/esp-idf@63aa0d6e9c
2022-05-27 17:44:23 +04:00
9d9aac1569 esp-netif: support for ipv6 addr types and indices
* Original commit: espressif/esp-idf@56725fa678
2022-05-27 17:44:23 +04:00
ef9a758662 Add multi-target support for performance tests
* Original commit: espressif/esp-idf@15884eccf2
2022-05-27 17:44:23 +04:00
2a23f355c7 examples: enable IPv6 in example common connect for esp32s2
Closes IDF-1115


* Original commit: espressif/esp-idf@0927ac648f
2022-05-27 17:44:23 +04:00
07399011f7 examples: common connect code to ignore GOT_IP6_EVENT if comes from unrelated netif
* Original commit: espressif/esp-idf@48fe3a13f5
2022-05-27 17:44:23 +04:00
2b7d43e1f8 mdns: limit the GOT_IP6_EVENT to only known network interfaces
* Original commit: espressif/esp-idf@ab8cab1c55
2022-05-27 17:44:23 +04:00
7bf23a7fe9 doc: Changed Chinese doc to use dynamic chip name
* Original commit: espressif/esp-idf@cfeb9e68cb
2022-05-27 17:44:23 +04:00
881ca095f0 doc: Update English pages with generic target name
* Original commit: espressif/esp-idf@9352899d69
2022-05-27 17:44:23 +04:00
d9fa457b4f docs: add new top-level docs builder that builds docs for a single chip
* Original commit: espressif/esp-idf@e6211c7864
2022-05-27 17:44:23 +04:00
4eb3e89841 esp32: add implementation of esp_timer based on TG0 LAC timer
Closes: IDF-979


* Original commit: espressif/esp-idf@739eb05bb9
2022-05-27 17:44:23 +04:00
74aee42f80 ethernet: work with cache disabled
add ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE flag, make ethenret driver
possible to work when cache disabled

Closes https://github.com/espressif/esp-idf/issues/4406


* Original commit: espressif/esp-idf@5ad0bdd8db
2022-05-27 17:44:23 +04:00
b5e5a64e7f mdns: fixed typos in the variable names and the comments
* Original commit: espressif/esp-idf@ecca39e19f
2022-05-27 17:44:23 +04:00
6713ffedcc mdns: fix preset of esp_netif ptr for local interfaces
mdns module store local copy of esp_netif for common interfaces,
but it was correctly initialized only when interface started.
If the event were missed (e.g. mdns_init after interface start)
the local copy wouldn't be initialized. Fixed by restoring the local
copy.

Closes WIFI-1538


* Original commit: espressif/esp-idf@09e36f9f33
2022-05-27 17:44:23 +04:00
817c4fd2e8 mdns: fixed crash on event during deinit
mdns library deinitialization destroys internal structures including action queue. if an event (e.g. network update) received
after some essential stucture is destoyed, an unexpected behavour might be introduced (e.g. crash of adding the event notification
to the action queue which was already destroyed

Closes WIFI-1485


* Original commit: espressif/esp-idf@eaa2f12d67
2022-05-27 17:44:23 +04:00
8f0dc6d578 mdns: respond to discovery with the proper pseudo name _services._dns-sd._udp
Closes https://github.com/espressif/esp-idf/issues/4369
Closes IDFGH-2219


* Original commit: espressif/esp-idf@de17a1487f
2022-05-27 17:44:23 +04:00
7a3aa26df8 test: update example and unit tests with new import roles:
tiny_test_fw is a python package now. import it using normal way.


* Original commit: espressif/esp-idf@c906e2afee
2022-05-27 17:44:23 +04:00
c7ff8ba0c9 ethernet: warning when double start/stop
* Original commit: espressif/esp-idf@ac11545e0a
2022-05-27 17:44:23 +04:00
80ce63d73e ethernet: move netif glue && add ref counter
1. move netif glue into single file
2. add reference counter for Ethernet driver


* Original commit: espressif/esp-idf@c3ee156df0
2022-05-27 17:44:23 +04:00
d20666f3a0 mdns: fixed forgotten merge conflicts in debug code
* Original commit: espressif/esp-idf@d9433ef692
2022-05-27 17:44:23 +04:00
cd3cc0be3b ethernet: add gpio number into config structure
* Original commit: espressif/esp-idf@05d71319de
2022-05-27 17:44:23 +04:00
1734e59057 zh_CN translation of mdns service
* Original commit: espressif/esp-idf@9691a755f6
2022-05-27 17:44:23 +04:00
662a4ce050 mdns: add missing include of esp_task.h
* Original commit: espressif/esp-idf@5884b80908
2022-05-27 17:44:23 +04:00
fb1de80fd7 mdns: add configuration values for task priority, affinity and internal service timeouts
closes https://github.com/espressif/esp-idf/issues/4217


* Original commit: espressif/esp-idf@c6f38f04f8
2022-05-27 17:44:23 +04:00
1f35e9a728 tcpip_adapter: updated tcpip_adapter compatablity layer to include all
public API and keep 100% backward compatibility
update build of tcpip adapter when ethernet disabled


* Original commit: espressif/esp-idf@7f5cda1b82
2022-05-27 17:44:23 +04:00
573855031d esp_netif: extract wifi_netif module as an abstraction to wifi universal interface defined by if handle and callback
* Original commit: espressif/esp-idf@20add7da60
2022-05-27 17:44:23 +04:00
d1c62628b8 esp_netif and examples: using wifi driver handle, update examples and tests to pass the CI
* Original commit: espressif/esp-idf@3a19bf055d
2022-05-27 17:44:23 +04:00
48b819bbc1 mdns: update mdns to use esp-netif for mdns supported services such as STA, AP, ETH
removes also include dependency on lwip to use esp_netif defined address fields and structures


* Original commit: espressif/esp-idf@19e24fe61e
2022-05-27 17:44:23 +04:00
dfcefc38fd examples: protocol examples which use common connection component
updated to use esp_netif_init instead of tcpip_adapter in initialization code


* Original commit: espressif/esp-idf@a49b934ef8
2022-05-27 17:44:23 +04:00
879a6cdfa3 examples: common component initialization code to use new esp_netif
instead of tcpip_adapter


* Original commit: espressif/esp-idf@21464465ea
2022-05-27 17:44:23 +04:00
53e2aa3241 esp_netif: Introduction of esp-netif component as a replacement of tcpip_adpter
- provides object oriented access to network intefaces
- not limited to default netifs
- more generic abstraction to network input output functions
- event handler registration removed from component responsibility
- backward compatibility layer for legacy tcpip_apapter APIs

Closes IDF-39


* Original commit: espressif/esp-idf@ffe043b1a8
2022-05-27 17:44:23 +04:00
3cc64469c1 examples: removed ip4addr_ntoa and used prefered IP2STR for displaying IP addresses
* Original commit: espressif/esp-idf@ec9f245dd3
2022-05-27 17:44:23 +04:00
248b11bb0a esp_event, mdns: fixes for CONFIG_ETH_ENABLED=n
* Original commit: espressif/esp-idf@569ad7545c
2022-05-27 17:44:23 +04:00
d52dddfea5 ci: limit example test to ESP32s
* Original commit: espressif/esp-idf@63329b169b
2022-05-27 17:44:23 +04:00
67d310b988 run WiFi on ESP32SBETA
* Original commit: espressif/esp-idf@99ef587a05
2022-05-27 17:44:23 +04:00
901124b7ee build and link hello-world for esp32s2beta
* Original commit: espressif/esp-idf@84b2f9f14d
2022-05-27 17:44:23 +04:00
f6ff165be9 mdns: fix crash for hostname queries
Receiving TXT, PTR, SDPTR and SRV record type queries would crash the application if the hostname
 was used as instance name.

Closes https://github.com/espressif/esp-idf/issues/4224


* Original commit: espressif/esp-idf@3d1170031b
2022-05-27 17:44:23 +04:00
d8d6b35553 mdns: updated example test to exercise also hostnames resolved by lwip gethostbyname and getaddrinfo
* Original commit: espressif/esp-idf@f3cb91ef71
2022-05-27 17:44:23 +04:00
f44c569422 mdns: fix possible race condition when checking DHCP status on WIFI_EVENT_STA_CONNECTED event.
tcpip_adapter_dhcpc_get_status() returns the actual internal value of dhcp client without any locking or TCP/IP stack context call, so when CONNECTED event fired with default settings it started DHCP client in TCP/IP stack context and at the same time mdns event handler checking actual DHCP state, which could still be INIT (not STARTED). Purpose of this check is to enable PCB if DHCP was stopped before setting network interface up (typically static IP settings), so the solutin is to check against TCPIP_ADAPTER_DHCP_STOPPED state


* Original commit: espressif/esp-idf@7f410a0bcb
2022-05-27 17:44:23 +04:00
7dfe14c83d ethernet: support OpenCores ethernet MAC
OpenCores Ethernet MAC has a relatively simple interface, and is
already supported in QEMU. This makes it a good candidate for enabling
network support when running IDF apps in QEMU, compared to the
relatively more complex task of writing a QEMU model of ESP32 EMAC.

This driver is written with QEMU in mind: it does not implement or
handle things that aren't implemented or handled in the QEMU model:
error flags, error interrupts. The transmit part of the driver also
assumes that the TX operation is done immediately when the TX
descriptor is written (which is the case with QEMU), hence waiting for
the TX operation to complete is not necessary.

For simplicity, the driver assumes that the peripheral register
occupy the same memory range as the ESP32 EMAC registers, and the
same interrupt source number is used.


* Original commit: espressif/esp-idf@31dac92e5f
2022-05-27 17:44:23 +04:00
286c646725 mdns: use constant size of AAAA answer in mdns packets instead of deriving from lwip struct size, since the struct could contain also zones
closes WIFI-771


* Original commit: espressif/esp-idf@e5e31c5d01
2022-05-27 17:44:23 +04:00
0582187b9a examples: gracefully shut down Wi-Fi before restart
This fixes the issue that if Wi-Fi is stopped from a shutdown handler,
the code in connect.c tries to reconnect, and fails because Wi-Fi is
already stopped.
Also make the error check in connect.c less strict.


* Original commit: espressif/esp-idf@28a440521e
2022-05-27 17:44:23 +04:00
28d5b74a00 ethernet: update spi-ethernet api
* Original commit: espressif/esp-idf@546ac64a9e
2022-05-27 17:44:23 +04:00
c70d527d80 esp_wifi: wifi support new event mechanism
1. WiFi support new event mechanism
2. Update examples to use new event mechanism


* Original commit: espressif/esp-idf@003a9872b7
2022-05-27 17:44:23 +04:00
7cdf96cffa mdns: fix missing bye packet if services removed with mdns_service_remove_all() or mdns_free()
Closes https://github.com/espressif/esp-idf/issues/3660


* Original commit: espressif/esp-idf@a001998d52
2022-05-27 17:44:23 +04:00
407875d9c5 mdns: mdns_service_remove_all doesn't take an argument
Merges https://github.com/espressif/esp-idf/pull/2937


* Original commit: espressif/esp-idf@c2764f6fe8
2022-05-27 17:44:23 +04:00
3e753f5e2d tools: Mass fixing of empty prototypes (for -Wstrict-prototypes)
* Original commit: espressif/esp-idf@afbaf74007
2022-05-27 17:44:23 +04:00
aaba3fc47a examples: change default build instructions in docs to CMake
* Original commit: espressif/esp-idf@e7dba7d7bc
2022-05-27 17:44:23 +04:00
144d4ad1d4 mdns: fix ignoring mdns packet with some invalid name entries in question field
In case of invalid name entry, only this entry is invalidated and parsing continues as other query entries could contain questions to be responded to


* Original commit: espressif/esp-idf@4bd4c7caf3
2022-05-27 17:44:23 +04:00
e431b6b7fe build system: Use CMake-based build system as default when describing commands
* Original commit: espressif/esp-idf@47bbb107a8
2022-05-27 17:44:23 +04:00
ed71a239a8 ethernet: support dm9051
1. move resource allocation from xxx_init to xxx_new
2. fix enabling tx checksum insertion by mistake
3. iperf example: enlarge max arguments
4. add examples for spi-ethernet

Closes https://github.com/espressif/esp-idf/issues/3715
Closes https://github.com/espressif/esp-idf/issues/3711


* Original commit: espressif/esp-idf@cb42c29252
2022-05-27 17:44:23 +04:00
680bad646f add esp_eth component
* Original commit: espressif/esp-idf@90c4827bd2
2022-05-27 17:44:23 +04:00
271665e0cb examples: use new component registration api
* Original commit: espressif/esp-idf@6771eead80
2022-05-27 17:44:23 +04:00
7fb6686716 components: use new component registration api
* Original commit: espressif/esp-idf@9eccd7c082
2022-05-27 17:44:23 +04:00
4912bef740 mdns: fix static analysis warnings
* Original commit: espressif/esp-idf@c34de4cba6
2022-05-27 17:44:23 +04:00
181a22ec2b mdns: added initial suite of api unit tests
* Original commit: espressif/esp-idf@e6801912c5
2022-05-27 17:44:23 +04:00
4172219225 mdns tests: adapt mdns fuzzer test to compile with event loop library
* Original commit: espressif/esp-idf@38d15cbd63
2022-05-27 17:44:23 +04:00
9a0803ad7e Rename Kconfig options (examples)
* Original commit: espressif/esp-idf@151f757912
2022-05-27 17:44:23 +04:00
05ddd5f0e4 Rename Kconfig options (components/esp32)
* Original commit: espressif/esp-idf@0ae53691ba
2022-05-27 17:44:23 +04:00
7e3b35efd9 mdns: documentation: fixed inconsistent enum in example of reading mdns results
* Original commit: espressif/esp-idf@786f5641f7
2022-05-27 17:44:23 +04:00
98d2c1a073 mdns: fixed mdns crashing on reception of txt packet without a corresponding service
closes #2866


* Original commit: espressif/esp-idf@af48977f21
2022-05-27 17:44:23 +04:00
84cbb1f3cf mdns: use const char* for mdns txt items types to remove warning when assigning
* Original commit: espressif/esp-idf@c050a75616
2022-05-27 17:44:23 +04:00
4c6818ee97 mdns: updated doxygen comments documenting mdns api
Closes https://github.com/espressif/esp-idf/issues/1718


* Original commit: espressif/esp-idf@a851aac255
2022-05-27 17:44:23 +04:00
c440114d14 mdns: update mdns_out_question_s to be in line with mdns_parsed_question_s struct
Closes  https://github.com/espressif/esp-idf/issues/1568


* Original commit: espressif/esp-idf@eddd5c4f2c
2022-05-27 17:44:23 +04:00
c0f65a6997 mdns example: Remove a warned unused constant
* Original commit: espressif/esp-idf@453a33ce79
2022-05-27 17:44:23 +04:00
778eaa6ced examples/protocols/mdns: use common network component
* Original commit: espressif/esp-idf@9628c60a1d
2022-05-27 17:44:23 +04:00
25f8656fbc examples: add component for protocol examples network functionality
* Original commit: espressif/esp-idf@22bef90bd3
2022-05-27 17:44:23 +04:00
6ea0ea93fa mdns: use esp_event library to handle events
* Original commit: espressif/esp-idf@a2d59525e5
2022-05-27 17:44:23 +04:00
d9aec9fc71 fuzzer tests: update of mdns and lwip host compilation for fuzzer testing
Closes IDF-540


* Original commit: espressif/esp-idf@bc60bbbeaf
2022-05-27 17:44:23 +04:00
985e69117e mdns: fix possible crash when probing on particular interface with duplicated service instances due to naming conflicts on network
Issue: MDNS server initially sends probing packets to resolve naming confilicts with already registered service instances. In case of a conflict, instance name is altered and probing restarts. Original instance however wasnnot removed from the structure and upon service removal only one entry was removed and a dangling service might have been kept in the structure to bring about a crash.
Resolution: Keep only one instance of a service in the probing structure.

Closes IDF-498


* Original commit: espressif/esp-idf@265e983a45
2022-05-27 17:44:23 +04:00
75deebbf03 mdns: enable pcbs before starting service thread to avoid updating pcb's internal variables from concurent tasks
possible race condition: user task runs mdns_init, which enables pcbs while mdns-task already created could execute enable/disable of the same pcbs if an appropriate system event received


* Original commit: espressif/esp-idf@c87f0cb6ca
2022-05-27 17:44:23 +04:00
fdd27dc9fa mdns: fix possible deadlock on mdns deinit calling mdns_free()
mnds_free() initiates stop and delete timer tasks, which after locking the mutex could lead to a dead lock in case timer task executed before deleting the task, as it would wait indefinitelly for unlocking the mutex. This condition is fixed by calling _mdns_stop_timer without locking the mutex, because there's no need to protect any data when stopping and deleting the timer task

Closes https://github.com/espressif/esp-idf/issues/1696


* Original commit: espressif/esp-idf@48b5501c25
2022-05-27 17:44:23 +04:00
2ec3b558ea mdsn: fix race condition in updating packet data from user task when failed to allocate or queue a new service
Issue: mdns_service_add API allocates and queues an action to be processed in mdns task context; when allocation or queueing fails, allocated structure needs to be freed. Function _mdns_free_service did not only fee all the structures, but also updates packet data.
Resolution: Moved removal of packet data outside of _mdns_free_service function.


* Original commit: espressif/esp-idf@021dc5d453
2022-05-27 17:44:23 +04:00
450cbf03cf mdns: fix possible crash when packet scheduled to transmit contained service which might have been already removed
packets scheduled to transmit are pushed to action queue and removed from tx_queue_head structure, which is searched for all remaining services and while service is removed, then service questions/asnwers are also removed from this structure. This update fixes possible crash when packet is pushed to action queue, and when service is removed, its answers are removed from tx_queue_head, but not from action queue. this could lead to a crash when the packet is poped from action queue containing questions/answers to already removed (freed) service

Closes IDF-504


* Original commit: espressif/esp-idf@67051a286b
2022-05-27 17:44:23 +04:00
34f6d8dd33 mdns: use binary semaphore instead of mutex when searching
mdns_search_once_t::lock is used to synchronize tasks (taken by one
task and given by the other) so it should not be a mutex.
Convert to semaphore, and rename to indicate its purpose.


* Original commit: espressif/esp-idf@eef0b5090a
2022-05-27 17:44:22 +04:00
b6efc688b5 mdns: fix memory leak in pbuf if tcpipadapter failed to get netif
* Original commit: espressif/esp-idf@8462751f95
2022-05-27 17:44:22 +04:00
11e4aebefd mdns example: fix print result for IPv6 addresses
* Original commit: espressif/esp-idf@fbef5297fc
2022-05-27 17:44:22 +04:00
90e4babc61 mdns: fix malfuctional query_txt
when running a query for a single txt, result entries were not created and attached to result structure. this issue was introduced when fixing memory leak in txt structure, which worked correctly for PTR queries, but caused trouble for TXT query.


* Original commit: espressif/esp-idf@1a027734af
2022-05-27 17:44:22 +04:00
c546ab8dea mdns: fix possible crash when mdns_free called while action queue not empty
* Original commit: espressif/esp-idf@206b47c03a
2022-05-27 17:44:22 +04:00
6582b41cd1 mdns: fix memory leak when query for service receives multiple ptr entries for one instance
fixes redmine issue 27300


* Original commit: espressif/esp-idf@9a4da97fb4
2022-05-27 17:44:22 +04:00
358d26c8a1 mdns: fix crash after init if no memory for task
mdns init first starts timer task, then starts service task. if service task failed to be created, timer task needs to be stopped too.
fixed https://ezredmine.espressif.cn:8765/issues/28466


* Original commit: espressif/esp-idf@a47768dc4e
2022-05-27 17:44:22 +04:00
8d08e5ed95 mdns tests: execute test services only when running example in ci
Test services may cause confussion (and did cause some GitHub/forum issues). This update runs test services only when example executed in ci. Also host name is a simple config entry if executed outside of ci.


* Original commit: espressif/esp-idf@74cc7a065f
2022-05-27 17:44:22 +04:00
2ac83d0f27 mdns: fixed crash on free undefined ptr after skipped strdup
Shortcircuit evaluation may cause skip of _mdns_strdup_check of any further question field, which after clear_rx_packet freed undefined memory.
Fixes https://ezredmine.espressif.cn:8765/issues/28465


* Original commit: espressif/esp-idf@e0a8044a16
2022-05-27 17:44:22 +04:00
98e3171db6 Correct Kconfigs according to the coding style
* Original commit: espressif/esp-idf@37126d3451
2022-05-27 17:44:22 +04:00
2f85c075be mdns: fix networking running udp_sendif from lwip thread
* Original commit: espressif/esp-idf@f7d4a4be6a
2022-05-27 17:44:22 +04:00
b30a7fec27 mdns: fixed static memory leak
* Original commit: espressif/esp-idf@6bb68a5a75
2022-05-27 17:44:22 +04:00
7a4fdad16d mdns: check all mallocs for failure and add default hook to log error with free heap
solves crash about _mdns_result_txt_create when stress test


* Original commit: espressif/esp-idf@c8cb4cd3c8
2022-05-27 17:44:22 +04:00
b4e57424f9 mdns: resolve memory leak when txt record received multiple times
* Original commit: espressif/esp-idf@a6b2b73f03
2022-05-27 17:44:22 +04:00
2763bcdb8d mdns: skip sending search when finished, not properly locked timer task
* Original commit: espressif/esp-idf@31163f02d5
2022-05-27 17:44:22 +04:00
dce0b26ef8 examples: Fix Python coding style
* Original commit: espressif/esp-idf@57c54f96f1
2022-05-27 17:44:22 +04:00
ade4aeffa5 mdns: added example test for ci runners
* Original commit: espressif/esp-idf@6309643c1d
2022-05-27 17:44:22 +04:00
8cd0e8a501 mdns: sending search packets also in probing and announcing state
mdns queries did not work properly when send imeadiately after set_hostname, which cuased reinit of pcb and therefore restarted probing, so search packets were blocked until probing finished
closes #2507, closes #2593


* Original commit: espressif/esp-idf@d16762a036
2022-05-27 17:44:22 +04:00
9b3b41c3f1 mdns: fixed crashes on network changes
1) two events AP_STOP, AP_START shortly after each other may cause IGMP config on already stopped netif
2) not properly locked sending packets to queue from timer task

closes #2580


* Original commit: espressif/esp-idf@097282a8e3
2022-05-27 17:44:22 +04:00
ea2300753e Update network code for mDNS to work with newest LwIP
- Uses one PCB that listens to all interfaces
- Manages multicast groups for each interface


* Original commit: espressif/esp-idf@3ec0e7e2d2
2022-05-27 17:44:22 +04:00
81c219d4ee feat(mdns): fix bug when clean action memory
* Original commit: espressif/esp-idf@3d4deb9726
2022-05-27 17:44:22 +04:00
0c17121ad7 bugfix: mdns_service_txt_set() wasn't allocating memory for TXT records
Allocation was happening later, causing possible use of stack variables
of caller function, which could be invalid.

Signed-off-by: Piyush Shah <piyush@espressif.com>


* Original commit: espressif/esp-idf@e5e2702ca3
2022-05-27 17:44:22 +04:00
67173f6770 cmake: make main a component again
* Original commit: espressif/esp-idf@d9939cedd9
2022-05-27 17:44:22 +04:00
fed787f54f Feature/sync lwip as submodule
* Original commit: espressif/esp-idf@3578fe39e0
2022-05-27 17:44:22 +04:00
b4ab30b5de mdns: Fix a portion of the queries are issued with the wildcard query type
* Original commit: espressif/esp-idf@f3f0445f4d
2022-05-27 17:44:22 +04:00
dd714947d6 added CI job for AFL fuzzer tests
* Original commit: espressif/esp-idf@0c147648f7
2022-05-27 17:44:22 +04:00
39de491597 mdns: Minor fix for mdns_service_remove()
Send the Goodbye packet while removing an mDNS service as an "Authoritative" packet so
that the listeners remove the service from their records immediately.


* Original commit: espressif/esp-idf@5c7eb7e27b
2022-05-27 17:44:22 +04:00
19acac76eb Replace all DOS line endings with Unix
Command run was:
git ls-tree -r HEAD --name-only | xargs dos2unix


* Original commit: espressif/esp-idf@a67d5d89e0
2022-05-27 17:44:22 +04:00
0191d6fcd7 fix(mdns): add the maximum number of services
* Original commit: espressif/esp-idf@ba458c69cf
2022-05-27 17:44:22 +04:00
b26c8665f8 fix(mdns): fix the exception when remove one of multiple service
* Original commit: espressif/esp-idf@696d733eb0
2022-05-27 17:44:22 +04:00
98069f9ca2 remove executable permission from source files
* Original commit: espressif/esp-idf@cb649e452f
2022-05-27 17:44:22 +04:00
ad29d34bb6 Fixed nullptr dereference in MDNS.c
* Original commit: espressif/esp-idf@fffbf7b750
2022-05-27 17:44:22 +04:00
9f1be3668e MDNS-Fuzzer: AFL fuzzer tests for mdsn packet parser
* Original commit: espressif/esp-idf@e983230be9
2022-05-27 17:44:22 +04:00
450c9de67b Fix potential NULL pointer dereference crash.
* Original commit: espressif/esp-idf@be707f1c6b
2022-05-27 17:44:22 +04:00
c7701d41f8 cmake: Add component dependency support
Components should set the COMPONENT_REQUIRES & COMPONENT_PRIVATE_REQUIRES variables to define their
requirements.


* Original commit: espressif/esp-idf@1cb5712463
2022-05-27 17:44:22 +04:00
b9726db48e cmake: Add CMakeLists.txt files for all examples
Generating using convert_to_cmake.py, with some minor cleanup


* Original commit: espressif/esp-idf@800bffb8b0
2022-05-27 17:44:22 +04:00
f1ccc4052e cmake: Remove defaults for COMPONENT_SRCDIRS, COMPONENT_SRCS, COMPONENT_ADD_INCLUDEDIRS
* Philosophical: "explicit is better than implicit".
* Practical: Allows useful errors if invalid directories given in components as the defaults aren't
  always used. Also trims the -I path from a number of components that have no actual include
  directory.
* Simplifies knowing which components will be header-only and which won't


* Original commit: espressif/esp-idf@4f1a856dbf
2022-05-27 17:44:22 +04:00
84bd1d7e88 build system: Initial cmake support, work in progress
* Original commit: espressif/esp-idf@c671a0c3eb
2022-05-27 17:44:22 +04:00
259d3fc609 fix the bug that in mdns test code redefine esp_err_t to uint32_t, which should be int32_t
* Original commit: espressif/esp-idf@81e4cad615
2022-05-27 17:44:22 +04:00
6d99957f2d Fix Kconfig.projbuild in some examples, where myssid is erroneously kept as the default value for password.
Signed-off-by: Hrishikesh Dhayagude <hrishi@espressif.com>


* Original commit: espressif/esp-idf@59d19d12af
2022-05-27 17:44:22 +04:00
7784d002fc Fix exception when service is removed while there are pending packets that depend on it
* Original commit: espressif/esp-idf@421c6f154b
2022-05-27 17:44:22 +04:00
9ebd9852ca Examples: Demonstrate the usage of esp_err_to_name
* Original commit: espressif/esp-idf@27a63c492f
2022-05-27 17:44:22 +04:00
26f00e8ddb Moved files into separate folders per 'en' and 'zh_CN' language version and linked 'zh_CN' files back to 'en' files if translation is not yet available
* Original commit: espressif/esp-idf@097adc3a33
2022-05-27 17:44:22 +04:00
bce7d5231c mdns: Fix case where service is NULL and that will cause exception
* Original commit: espressif/esp-idf@4fa130ae4f
2022-05-27 17:44:22 +04:00
ef924f1aa5 mdns: Fix issue with some mDNS parsers
Some mDNS parser have issue with zero terminated TXT lists. This fix targets to overcome this issue. Found and tested with jmdns.


* Original commit: espressif/esp-idf@51dde19a76
2022-05-27 17:44:22 +04:00
ad8c92db52 Import mDNS changes
* Original commit: espressif/esp-idf@4bddbc031c
2022-05-27 17:44:22 +04:00
3aa605fe24 Fix compilation errors when using gcc-7.2.0 for the crosstool-ng toolchain
* Change snprintf for strlcat does not complain w/gcc7.2.0 and it is safer, thanks @projectgus
* Use proper quotes for character literals

Merges https://github.com/espressif/esp-idf/pull/1163


* Original commit: espressif/esp-idf@519edc332d
2022-05-27 17:44:22 +04:00
00a72b8920 components/mdns: wrong Message compression detect
Old behavior assumes message compressed when any of 2 most significant bits are set,
But in fact Message compressed only when both those bits are set to 1.

Also maximal label length should be 63 bytes.


* Original commit: espressif/esp-idf@6e24566186
2022-05-27 17:44:22 +04:00
907e7ee29e mdns: fix leak after _mdns_create_service if we have a malloc error.
* Original commit: espressif/esp-idf@b6b36bd9dd
2022-05-27 17:44:22 +04:00
b367484361 Use LwIP IPC for low-level API calls
* Original commit: espressif/esp-idf@713964fe9e
2022-05-27 17:44:22 +04:00
4a8582f500 Add AFL fuzz test
* Original commit: espressif/esp-idf@4c2622755d
2022-05-27 17:44:22 +04:00
75de31cea3 implement fixes for issues found while fuzz testing
* Original commit: espressif/esp-idf@99d39909c4
2022-05-27 17:44:22 +04:00
4acf639afc mdns: add simple dns-sd meta query support
tabs to spaces

match domain


* Original commit: espressif/esp-idf@96e8a3c725
2022-05-27 17:44:22 +04:00
1a1cf71a84 examples: Standardise naming of files, symbols, etc. in examples
* Use "example" in all example function & variable names,
  ie use i2c_example_xxx instead of i2c_xxx for example functions.
  Closes #198 https://github.com/espressif/esp-idf/issues/198
* Mark example functions, etc. static
* Replace uses of "test" & "demo" with "example"
* Split the UART example into two
* Rename "main" example files to end with "_main.c" for disambiguation


* Original commit: espressif/esp-idf@821c70f5d7
2022-05-27 17:44:22 +04:00
5924dafd94 examples: check return value of nvs_flash_init
nvs_flash_init may return an error code in some cases, and applications
should check this error code (or at least assert on it being ESP_OK, to
make potential issues more immediately obvious).

This change modifies all the examples which use NVS to check the error
code. Most examples get a simple ESP_ERROR_CHECK assert, while NVS
examples, OTA example, and NVS unit tests get a more verbose check which
may be used in real applications.


* Original commit: espressif/esp-idf@4813ab2d28
2022-05-27 17:44:22 +04:00
91bb5095f5 address security issues with mDNS
* Original commit: espressif/esp-idf@c89e11c8fa
2022-05-27 17:44:22 +04:00
caa4884b3a Added README.md to example category folders
* Original commit: espressif/esp-idf@0b6598c492
2022-05-27 17:44:22 +04:00
441a53c604 Moved examples to new folders / categories. Removed example numbers from example names
* Original commit: espressif/esp-idf@382999b378
2022-05-27 17:44:22 +04:00
7fbf8e5247 Initial mDNS component and example
* Original commit: espressif/esp-idf@dd3f18d2d8
2022-05-27 17:44:22 +04:00
7346ed9765 Merge pull request #24 from gabsuren/ci/websocket_add_test_job
CI: Added pytest example for websocket (IDFGH-7253)
2022-05-26 11:37:39 +02:00
76298ff70e CI: Added CI example run job 2022-05-25 20:12:38 +04:00
0875008a46 Merge pull request #30 from Sjurinho/feature/extended-simcom-support
Feature/extended simcom support (IDFGH-7243)
2022-05-25 13:21:50 +02:00
a661e51f7e esp_modem: Fix param description for get_operator_name()
Co-authored-by: Franz Höpfinger <krone-trailer@franzhoepfinger.de>
2022-05-24 17:44:35 +02:00
3ced2d9709 Update: Removed stringstream to decrease static sizes 2022-05-24 14:54:24 +02:00
ba88d7fdbc Update: Renamed list_in to be type-specific
Update: Removed modem-specific comment
2022-05-24 14:53:58 +02:00
4f3c4299d6 Update: Changed tests to coincide with new initial esp_modem mode 2022-05-24 14:53:11 +02:00
2a4e684848 Merge pull request #34 from david-cermak/bugfix/modem_cmux_uih
fix(esp_modem): Correction of switching to CMUX mode
2022-05-24 10:38:59 +02:00
541b391c3e Merge pull request #40 from gabsuren/docs/esp_websocket_client_readme
DOC: Updated README.md regarding esp_websocket_client
2022-05-24 10:28:10 +02:00
279a3cb6e0 DOC: Updated README.md regarding esp_websocket_client 2022-05-23 17:08:35 +04:00
60bb0eea99 Merge pull request #36 from diplfranzhoepfinger/feature/dte
typo (IDFGH-7360)
2022-05-15 15:54:49 +02:00
52de8f1b2a typo 2022-05-13 17:29:34 +02:00
503218b3ba fix(esp_modem): Correction of switching to CMUX
* BG96 needs a small pause between CMUX command reception and actual use
of the CMUX mode
* Correct CMUX payload reception to check FT_UIH message type (P/F flag
could be cleared or set)

Closes https://github.com/espressif/esp-protocols/issues/33
2022-05-10 18:04:18 +02:00
38149c8d9b Merge pull request #22 from 0xFEEDC0DE64/websocket_client_change_ping_interval
Add methods to allow get/set of websocket client ping interval (IDFGH-7096)
2022-05-03 09:26:54 +02:00
1984da150d Merge pull request #23 from 0xFEEDC0DE64/websocket_client_error
Implement websocket client connect error (IDFGH-7245)
2022-04-27 15:52:17 +02:00
9e37f537bd Implement websocket client connect error 2022-04-26 11:15:57 +02:00
e55f54b69e Add methods to allow get/set of websocket client ping interval 2022-04-26 11:06:20 +02:00
6e4d8a19ed Merge pull request #29 from MacDue/expose_fin
esp_websocket_client: Expose frame fin flag in websocket event
2022-04-26 08:47:15 +02:00
e98cf16859 Update: Removed duplicate power down function
Add: gnss power mode function
2022-04-20 09:37:39 +02:00
be3d2ece55 Update: Formatting 2022-04-20 09:16:05 +02:00
15ed885035 Add: Sim7600 extended support 2022-04-19 16:23:22 +02:00
b72a9ae710 esp_websocket_client: Expose frame fin flag in websocket event 2022-04-15 17:06:03 +01:00
0733ea8ff4 Add: Support for SIM7000 modules 2022-04-13 15:36:15 +02:00
15cbc9bd50 Update: modem_mode::UNDEF initially 2022-04-13 13:44:11 +02:00
bb7f198bea Add: sim7070 support 2022-04-13 13:42:57 +02:00
d3f7ea67fb Add: Expanded modem_command_library with more "standard" commands 2022-04-13 13:41:56 +02:00
6e5bede4c7 Merge pull request #28 from bitron/esp-modem_sim800_fix
esp_modem fix for SIM800 modem devices (IDFGH-7166)
2022-04-12 16:07:05 +02:00
d191a720d1 esp_modem: Fix DCE selection in ‘pppos_client’ example 2022-04-07 17:08:54 +02:00
cc0d52793b esp_modem: Fix AT command in ‘set_data_mode_sim8xx()’ for SIM800 modem device 2022-04-07 17:02:12 +02:00
804a8d5df6 Merge pull request #25 from tore-espressif/feature/usb_dte
Add USB DTE example
2022-04-04 16:05:29 +02:00
74040cfd1a esp_modem: Extend modem_console example with USB DTE 2022-04-04 15:48:47 +02:00
16ea3f7eb8 Merge pull request #21 from tore-espressif/fix/idf5.0
Fix IDFv5.0 include paths (IDFGH-6972)
2022-03-22 14:38:09 +01:00
1f5eb396c5 Fix IDFv5.0 include paths
Changed in commit a9fda54d39d1321005c3bc9b3cc268d0b7e9f052
2022-03-16 08:30:03 +01:00
827bebd2bc Merge pull request #20 from antmak/bugfix/passing_cmake_cxx_std_option
build: fix issue with passing cxx_std option, a common workaround (IDFGH-6876)
2022-03-04 12:49:51 +01:00
745201b188 build: fix issue with passing cxx_std option, a common workaround
issue: https://gitlab.kitware.com/cmake/cmake/-/issues/23297
2022-03-04 18:24:44 +07:00
ca266cabd0 Merge pull request #16 from david-cermak/update/modem_test_dynamic_poly
add(esp_modem): Add unit test to check polymorphic delete
2022-03-04 08:45:20 +01:00
e54b240870 add(esp_modem): Add unit test to check polymorphic delete 2022-03-04 08:37:22 +01:00
4ccc32ffb5 Merge pull request #19 from david-cermak/bugfix/fix_docs_build
CI: Fix docs build failure
2022-03-04 08:18:53 +01:00
91a177edd4 fix(ws_client): Docs to refer esp-protocols 2022-03-04 07:57:24 +01:00
f303cdc70b fix(CI): build docs & publish component failure 2022-03-04 07:44:45 +01:00
ab8c2da395 Merge pull request #18 from gabsuren/esp_websocket_client_migration_with_history
websocket: Initial version based on IDF 5.0 with history
2022-03-02 13:43:34 +01:00
80c3cf0f02 websocket: Initial version based on IDF 5.0 2022-03-02 15:48:43 +04:00
b3c777ad43 freertos: Remove legacy data types
This commit removes the usage of all legacy FreeRTOS data types that
are exposed via configENABLE_BACKWARD_COMPATIBILITY. Legacy types can
still be used by enabling CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY.


* Original commit: espressif/esp-idf@57fd78f5ba
2022-03-01 12:18:50 +04:00
8ce791e969 websocket: Added configs reconnect_timeout_ms and network_timeout_ms
Closes https://github.com/espressif/esp-idf/issues/8263


* Original commit: espressif/esp-idf@6c26d65203
2022-03-01 12:18:50 +04:00
fc7ed90d74 websocket: Updated Kconfig to use 'echo.websocket.events' echo server
Updated README to show how to run websocket echo server using Flask

Merges https://github.com/espressif/esp-idf/pull/8262


* Original commit: espressif/esp-idf@23598dfcec
2022-03-01 12:18:50 +04:00
59e82695e7 ws_client: Optimize example test payloads and timeouts
Important update: NO_DATA_TIMEOUT_SEC=5, as some ws-servers typically send pings in 30s or 10s intervals, so we might never fire shutdown test


* Original commit: espressif/esp-idf@323622be64
2022-03-01 12:18:50 +04:00
755f16222f ci/websockets: Run ws-client example test on ethernet runners
* Original commit: espressif/esp-idf@2649413ae8
2022-03-01 12:18:50 +04:00
bece6e7045 Add http_parser (new component) dependency
* Original commit: espressif/esp-idf@8e94cf2bb1
2022-03-01 12:18:50 +04:00
46bd32d952 websocket: removed deprecated API "esp_websocket_client_send"
Closes IDF-1470


* Original commit: espressif/esp-idf@7f6ab93f7e
2022-03-01 12:18:50 +04:00
525c70c0b2 refactor (test_utils)!: separate file for memory check functions
Memory check (leaks and heap tracing) functions for unit tests
now have a separate file now and are renamed for more consistency.

BREAKING CHANGE: renamed memory check function names which may be used
                 in unit tests outside IDF.


* Original commit: espressif/esp-idf@16514f93f0
2022-03-01 12:18:50 +04:00
c4c323666e docs: Fix spell and grammatical errors
- PCNT
- ESP-TLS
- ESP WebSocket Client


* Original commit: espressif/esp-idf@1df7f340be
2022-03-01 12:18:50 +04:00
19c0455b4d Build & config: Remove leftover files from the unsupported "make" build system
* Original commit: espressif/esp-idf@766aa57084
2022-03-01 12:18:50 +04:00
665c520faf [examples]: removed hyphens
Replaced hyphens with underscores in examples
project definition for all examples which had
hyphens in their project name. dpp-enrollee is
an exceptions because the name matches the
project directory name while the project
directory also contains hyphens.


* Original commit: espressif/esp-idf@81e9266204
2022-03-01 12:18:50 +04:00
9118e0f044 transport: Add CONFI_WS_TRANSPORT for optimize the code size
* Original commit: espressif/esp-idf@8b02c9026a
2022-03-01 12:18:50 +04:00
fbdbd550c0 ws_client: Fix const correctness in the API config structure
Merges https://github.com/espressif/esp-idf/pull/7113


* Original commit: espressif/esp-idf@70b1247a47
2022-03-01 12:18:50 +04:00
028be5a8d7 Split example_tests with Example_WIFI tag group into Example_OTA and Example_Protocols
* Original commit: espressif/esp-idf@0a395134d4
2022-03-01 12:18:50 +04:00
de7cd72f70 components: Remove repeated keep alive function by ssl layer function
In esp_http_client and esp_websocket_client components, esp_transport_tcp_set_keep_alive has been called and keep-alive config has been saved in ssl->cfg.keep_alive_cfg,
So no need to call esp_transport_ssl_set_keep_alive again.


* Original commit: espressif/esp-idf@c79a907e4f
2022-03-01 12:18:50 +04:00
4a608ec1cd components: Support bind socket to specified interface in esp_http_client and esp_websocket_client component
* Original commit: espressif/esp-idf@bead3599ab
2022-03-01 12:18:50 +04:00
f0351ff378 esp_websocket_client: Don't log the filename when logging "Websocket already stop"
Progress towards https://jira.espressif.com:8443/browse/IDFGH-4477


* Original commit: espressif/esp-idf@10bde42551
2022-03-01 12:18:50 +04:00
9219ff710a websocket: Add websocket unit tests
* Original commit: espressif/esp-idf@cd01a0ca81
2022-03-01 12:18:50 +04:00
86aa0b8d39 websockets: Set keepalive options after adding transport to the list
To be in line with other code and mainly to support base/foundation transport used by both tcp and ssl transport layers


* Original commit: espressif/esp-idf@99805d880f
2022-03-01 12:18:50 +04:00
1933367f63 websocket: Add configurable ping interval
Merges https://github.com/espressif/esp-idf/pull/6399

Signed-off-by: David Cermak <cermak@espressif.com>


* Original commit: espressif/esp-idf@9ff9137e7a
2022-03-01 12:18:50 +04:00
cf697a1a1b style: format python files with isort and double-quote-string-fixer
* Original commit: espressif/esp-idf@0146f258d7
2022-03-01 12:18:50 +04:00
95cf983502 ws_transport: Add option to propagate control packets to the app
Client could choose if they want to receive control packets and handle
them.
* If disabled (default) the transport itself tries to handle PING
and CLOSE frames automatically during read operation. If handled
correctly, read outputs 0 indicating no (actual app) data received.
* if enabled, all control frames are passed to the application to be
  processed there.

Closes https://github.com/espressif/esp-idf/issues/6307


* Original commit: espressif/esp-idf@acc7bd2ca4
2022-03-01 12:18:50 +04:00
8a6c320a29 Add options for esp_http_client and esp_websocket_client to support keepalive
* Original commit: espressif/esp-idf@b53e46a68e
2022-03-01 12:18:50 +04:00
d1dd6ece38 websocket: support mutual tls for websocket
Closes https://github.com/espressif/esp-idf/issues/6059


* Original commit: espressif/esp-idf@5ab774f9d8
2022-03-01 12:18:50 +04:00
36167db336 test: remove fake binary size check in example test:
the binary size check in example test was removed long time ago. Now we
have updated ttfw_idf to raise exception when performance standard is
not found. These fake performance check will be regarded as error.
Remove them now.


* Original commit: espressif/esp-idf@a908174c06
2022-03-01 12:18:50 +04:00
d376480766 Whitespace: Automated whitespace fixes (large commit)
Apply the pre-commit hook whitespace fixes to all files in the repo.

(Line endings, blank lines at end of file, trailing whitespace)


* Original commit: espressif/esp-idf@66fb5a29bb
2022-03-01 12:18:50 +04:00
e90272c812 Websocket client: avoid deadlock if stop called from event handler
* Original commit: espressif/esp-idf@c2bb0762bb
2022-03-01 12:18:50 +04:00
fda070ba39 ws_client tests: Updated example test to use WebsSocket package
Added a new test for closing connection with close frames


* Original commit: espressif/esp-idf@44c553fd14
2022-03-01 12:18:50 +04:00
6d12d06605 tcp_transport: Added internal API for underlying socket, used for custom select on connection end for WS
Internal tcp_transport functions could now use custom socket operations.
This is used for WebSocket transport, when we typically wait for clean
connection closure, i.e. selecting for read/error with expected errno or
recv size=0 while socket readable (=connection terminated by FIN flag)


* Original commit: espressif/esp-idf@5e9f8b52e7
2022-03-01 12:18:50 +04:00
1455bc0305 ws_client: Added support for close frame, closing connection gracefully
* Original commit: espressif/esp-idf@b213f2c6d3
2022-03-01 12:18:50 +04:00
01b4f640d9 driver, http_client, web_socket, tcp_transport: remove __FILE__ from log messages
__FILE__ macro in the error messages adds full paths to the production binarys, remove __FILE__ from the ESP_LOGE.

Closes https://github.com/espressif/esp-idf/issues/5637
Merges https://github.com/espressif/esp-idf/pull/5638


* Original commit: espressif/esp-idf@caaf62bdad
2022-03-01 12:18:50 +04:00
6ab0aea841 websocket_client : fix some issues for websocket client
1. will post twice disconnect event when read error
2. will block `timeout` times when set disable_auto_connect
3. When `esp_websocket_client_stop` before `esp_websocket_client_send*`,
if the `esp_websocket_client_send*` fails, the status will change to
 'WEBSOCKET_STATE_WAIT_TIMEOUT', and the next `esp_websocket_client_start` will fail forever


* Original commit: espressif/esp-idf@341e480573
2022-03-01 12:18:50 +04:00
5f2a50f09f doc/websocket: updates the API reference for ESP WebSocket Client
* Original commit: espressif/esp-idf@09f240c1e1
2022-03-01 12:18:50 +04:00
b71c49c277 websocket: add configurable timeout for PONG not received
Closes IDF-1744


* Original commit: espressif/esp-idf@0049385850
2022-03-01 12:18:50 +04:00
f8e3ba7813 websocket client: the client now aborts the connection if send fails.
Closes IDF-1744


* Original commit: espressif/esp-idf@6bebfc84f3
2022-03-01 12:18:50 +04:00
7a5b2d5a7d ws_client: fix fragmented send setting proper opcodes
Previous implementation violated the RFC by having both the actual opcode and WS_FIN flag set for all fragments of a message.
Fixed by setting the opcode only for the first fragment and WS_FIN for the last one

Closes IDFGH-2938
Closes https://github.com/espressif/esp-idf/issues/4974


* Original commit: espressif/esp-idf@14992e62c5
2022-03-01 12:18:50 +04:00
42920d7fb5 Fix format string in websocket example
* Original commit: espressif/esp-idf@5288a797ef
2022-03-01 12:18:50 +04:00
2b044f2434 Add multi-target support for performance tests
* Original commit: espressif/esp-idf@15884eccf2
2022-03-01 12:18:50 +04:00
2b6022c85d examples: websocket example to send textual data with esp_websocket_client_send_text()
Closes https://github.com/espressif/esp-idf/issues/4640


* Original commit: espressif/esp-idf@e5650d1ed8
2022-03-01 12:18:50 +04:00
fae2343b19 docs: add new top-level docs builder that builds docs for a single chip
* Original commit: espressif/esp-idf@e6211c7864
2022-03-01 12:18:50 +04:00
17281a515e esp32: add implementation of esp_timer based on TG0 LAC timer
Closes: IDF-979


* Original commit: espressif/esp-idf@739eb05bb9
2022-03-01 12:18:50 +04:00
aec6a75d40 tcp_transport/ws_client: websockets now correctly handle messages longer than buffer
transport_ws can now be read multiple times in a row to read frames larger than the buffer.

Added reporting of total payload length and offset to the user in websocket_client.

Added local example test for long messages.

Closes IDF-1083


* Original commit: espressif/esp-idf@ffeda3003c
2022-03-01 12:18:50 +04:00
a6be8e2e3d websocket: added missing event data
user_context was missing from websocket event data, added. Also added the websocket client handle to the event data.

Removed  unused event data struct.

Closes: IDF-1271


* Original commit: espressif/esp-idf@7c0e3765ec
2022-03-01 12:18:50 +04:00
09453e4694 esp_netif, examples: esp_netif_init() moved into ESP_ERROR_CHECK()
esp_netif_init() returns standard esp_err_t error code (unlike tcpip_adapter init), so shall be checked for the return value
Also to make the initialization code more consistent.


* Original commit: espressif/esp-idf@31b2702387
2022-03-01 12:18:50 +04:00
3b0488cfdc websocket_client: added example_test with a local websocket server
- Added a example test that connects to a local python websocket server.
- Added readme for websocket_client example.

Closes IDF-907


* Original commit: espressif/esp-idf@67c5225c14
2022-03-01 12:18:50 +04:00
f21a2f32e0 test: update example and unit tests with new import roles:
tiny_test_fw is a python package now. import it using normal way.


* Original commit: espressif/esp-idf@c906e2afee
2022-03-01 12:18:50 +04:00
a48b0fafe8 Add User-Agent and additional headers to esp_websocket_client
Merges https://github.com/espressif/esp-idf/pull/4345


* Original commit: espressif/esp-idf@9200250f51
2022-03-01 12:18:50 +04:00
1fcc001ae8 ws_client: fix handling timeouts by websocket client.
tcp-transport component did not support wait forever. this update uses value of -1 to request this state.
websocket client uses timeouts in RTOS ticks. fixed recalculation to ms (including special value of -1) to use correctly tcp-transport component

Closes https://github.com/espressif/esp-idf/issues/4316


* Original commit: espressif/esp-idf@e1f982921a
2022-03-01 12:18:50 +04:00
a41e3383b3 examples: protocol examples which use common connection component
updated to use esp_netif_init instead of tcpip_adapter in initialization code


* Original commit: espressif/esp-idf@a49b934ef8
2022-03-01 12:18:50 +04:00
d0121b964d websocket_client: fix locking mechanism in ws-client task and when sending data
closes https://github.com/espressif/esp-idf/issues/4169


* Original commit: espressif/esp-idf@7c5011f411
2022-03-01 12:18:50 +04:00
f55d8391c9 ws_client: fix for not sending ping responses, updated to pass events also for PING and PONG messages, added interfaces to send both binary and text data
closes https://github.com/espressif/esp-idf/issues/3982


* Original commit: espressif/esp-idf@abf9345b85
2022-03-01 12:18:50 +04:00
fe26b734b5 Cosmetic Kconfig fixes
* Original commit: espressif/esp-idf@d3ed17acd7
2022-03-01 12:18:50 +04:00
f5a26c4d32 websocket_client: fix URI parsing to include also query part in websocket connection path
closes https://github.com/espressif/esp-idf/issues/4090


* Original commit: espressif/esp-idf@271e6c4c9c
2022-03-01 12:18:50 +04:00
23f6a1d46e ws_client: fixed posting to event loop with websocket timeout
Executing event loop `esp_event_loop_run()` with timeout causes delays in receiving events from user code. Fixed by removing the timeout to post synchronously.

closes https://github.com/espressif/esp-idf/issues/3957


* Original commit: espressif/esp-idf@50505068c4
2022-03-01 12:18:50 +04:00
2553d65e64 ws_client: added subprotocol configuration option to websocket client
closes https://github.com/espressif/esp-idf/issues/3893


* Original commit: espressif/esp-idf@de6ea396f1
2022-03-01 12:18:50 +04:00
67949f94f4 ws_client: fixed path config issue when ws server configured using host and path instead of uri
closes https://github.com/espressif/esp-idf/issues/3892


* Original commit: espressif/esp-idf@c0ba9e19fc
2022-03-01 12:18:50 +04:00
bfc88ab76c ws_client: fixed transport config option when server address configured as host, port, transport rather then uri
closes https://github.com/espressif/esp-idf/issues/3891


* Original commit: espressif/esp-idf@adee25d90e
2022-03-01 12:18:50 +04:00
343fbfdcc9 ci: limit example test to ESP32s
* Original commit: espressif/esp-idf@63329b169b
2022-03-01 12:18:50 +04:00
4d644954fe esp_wifi: wifi support new event mechanism
1. WiFi support new event mechanism
2. Update examples to use new event mechanism


* Original commit: espressif/esp-idf@003a9872b7
2022-03-01 12:18:50 +04:00
da74a4a489 tools: Mass fixing of empty prototypes (for -Wstrict-prototypes)
* Original commit: espressif/esp-idf@afbaf74007
2022-03-01 12:18:50 +04:00
f718676083 ws_client: fix double delete issue in ws client initialization
* Original commit: espressif/esp-idf@9b507c45c8
2022-03-01 12:18:50 +04:00
13a40d2344 ws_client: removed dependency on internal tcp_transport header
* Original commit: espressif/esp-idf@d1433564ec
2022-03-01 12:18:50 +04:00
35d6f9a2c6 examples: use new component registration api
* Original commit: espressif/esp-idf@6771eead80
2022-03-01 12:18:50 +04:00
f3a0586663 esp_websocket_client: Add websocket client component
Closes https://github.com/espressif/esp-idf/issues/2829


* Original commit: espressif/esp-idf@2a2d932cfe
2022-03-01 12:18:50 +04:00
04a7643d67 Merge pull request #17 from mensi/implement-sync
Implement esp_modem_sync for the C API
2022-02-28 10:05:21 +01:00
8b3d420055 Implement esp_modem_sync for the C API 2022-02-23 17:49:58 +01:00
50b083a58c Merge pull request #14 from b1ackviking/fix-missing-virtual-dtors
fix: add virtual destructors to ModuleIf and CommandableIf
2022-02-23 11:01:48 +01:00
325a1933c4 fix: missing default statement in a switch in the modem_console example 2022-01-28 22:34:03 +07:00
face03e4e5 fix: add virtual destructors to ModuleIf and CommandableIf 2022-01-28 22:34:03 +07:00
5d27b2681a Merge pull request #10 from david-cermak/bugfix/modem_parse_battery_status
fix(esp_modem): Fix battery status parser
2021-12-07 16:03:00 +01:00
2cb74cf8d0 Update(esp_modem): Bump component version 2021-12-06 12:49:09 +01:00
d879e82a42 fix(esp_modem): Update the test to exersise CBC parser 2021-12-06 11:17:24 +01:00
4f1d31f9b7 fix(esp_modem): Fix battery status parse
Variable `pos`  was meant to hold position of first `,` (comma)
appearance in the parsed string, but due to wrong parantheses it
contained the boolean representation of not equal to `string::npos`
2021-12-06 11:17:24 +01:00
bece4efa09 Merge pull request #9 from david-cermak/bugfix/esp_modem_read_module_name
fix(esp_modem): Read module name with AT commands
2021-12-01 15:31:23 +01:00
8417e232aa fix(esp_modem): Read module name with AT commands
This fixes basic IDF test case which supplied dummy module name.
2021-11-25 16:24:52 +01:00
5f0832a0ad Merge pull request #7 from david-cermak/feature/ci_test_report
CI: Add run host to the CI
2021-11-18 15:42:33 +01:00
464baeeb83 Merge pull request #8 from sudeep-mohanty/master
esp_modem: Update FreeRTOS EventQueueHandle_t forward declaration
2021-11-18 12:13:17 +01:00
5d9ad9cffd esp_modem: Update FreeRTOS EventQueueHandle_t forward declaration
This commit includes freertos/event_groups.h header and removes the
forward declaration for EventGroupHandle_t.

Signed-off-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
2021-11-18 16:24:35 +05:30
9fbd6e658a CI: Build on linux and Run host tests 2021-11-18 08:35:55 +01:00
8465b14653 fix(esp_modem): linux port to work with lwip-2.1.2 2021-11-18 08:35:49 +01:00
e7ae0301ae Merge pull request #5 from david-cermak/bugfix/missign_c_api
fix(esp_modem): Add missing C API
2021-11-18 07:36:40 +01:00
96498760bf esp_modem: New version to publish to component registry 2021-11-16 08:13:26 +01:00
cf990d1a87 Docs: Add links to GitHub pages 2021-11-16 08:11:57 +01:00
5299b425e8 esp_modem: Add missing AT commands to plain C-API 2021-11-16 08:03:30 +01:00
bcb1ab99bd Merge pull request #4 from david-cermak/feature/build_docs
CI/Docs: Add jobs to deploy component docs
2021-11-16 07:56:50 +01:00
2c21aa1113 CI/Docs: Generate docs locally before uploading to registry 2021-11-16 07:51:24 +01:00
b9ff1e4e12 CI/Docs: Add jobs to deploy component docs 2021-11-12 16:51:21 +01:00
23dbdb584e Merge pull request #3 from david-cermak/feature/upload_components
Added actions to upload components and sync issues
2021-11-08 18:04:37 +01:00
1d0cc49c3f CI: Sync issues to JIRA 2021-11-08 15:18:44 +01:00
c1249aec17 CI: Upload comonents to Espressif Service on master
Co-authored-by: Sergei Silnov <po@kumekay.com>
2021-11-08 15:18:35 +01:00
2bbcb95e53 Merge pull request #2 from sudeep-mohanty/master
esp_modem: Update Task handle and Event Group handle to match freertos v10.4.3
2021-11-08 12:44:05 +01:00
58887170d2 esp_modem: Update Task handle and Event Group handle to match freertos v10.4.3
This commit updates the default handles for Task type and Signal Group
type to match the struct type handle from freertos v10.4.3.

Signed-off-by: Sudeep Mohanty <sudeep.mohanty@espressif.com>
2021-11-08 10:46:53 +05:30
cc7aa03a37 Merge pull request #1 from david-cermak/master
CI: Initial GitHub Action to build examples
2021-11-04 13:33:59 +01:00
15a858b735 CI: Move separate master job to the loop loop 2021-11-04 13:27:05 +01:00
01e2a9c109 Examples: Fix print format for http_client() API 2021-11-04 11:41:11 +01:00
c0021ceeb2 CI: Rewrite flat build jobs using test matrix 2021-11-04 11:33:28 +01:00
fec83e5915 CI: Initial GitHub Action to build examples
Build job definitions for building examples for ESP32 only against IDF
master, 4.4, 4.3, 4.2 and 4.1
2021-11-03 17:39:47 +01:00
c8c24ed2fc Examples: Fix build error when SIM needs no PIN 2021-11-03 13:59:24 +01:00
b380ded5fa Examples: Use bigger 4M flash for OTA example 2021-11-03 13:59:24 +01:00
38f6eb963a README: esp-protocol repository 2021-10-04 11:39:32 +02:00
2a2d27086f esp_modem(0.1.9): Fix CMake3.5 build with no cxx_std_17 feature
Older CMake (< 3.8, but still supported in IDF) doesn't support target_compile_features() for cxx_std_17.
If CMake doesn't know C++17 features, set it manually via comile options.
2021-10-04 11:35:27 +02:00
9dd1bd5ed0 esp_modem: 0.1.8: Update comonent version 2021-10-04 11:32:55 +02:00
918db0d2f1 Add pre upload script to deploy the docs before component upload 2021-10-04 11:32:55 +02:00
c1b1330680 esp_modem(Docs): Minor correction of the docs 2021-10-04 11:32:55 +02:00
fb7295e91a Examples/console: Remove unnecessary event-base check on IP handler 2021-10-04 11:32:55 +02:00
8236b3d490 Examples: Extend CMux client default stack size for the main task 2021-10-04 11:32:55 +02:00
fb6029b66c CMUX: Refactor the protocol decoder to multiple methods per cmux state 2021-10-04 11:32:55 +02:00
6e34954677 Factory: Rename Builder class to Creator, since it's not 100% builder pattern 2021-10-04 11:32:55 +02:00
148a9300a4 esp_modem: Formal updates per code review 2021-10-04 11:32:55 +02:00
1fb9150bcc Docs: Update CMux collaboration diagram to resemble composite 2021-10-04 11:32:55 +02:00
a61e9e2d40 Applied astyle code formatting 2021-10-04 11:32:55 +02:00
dc64f862c4 esp-modem(DCE-Factory): Minor corrections per code review 2021-10-04 11:32:55 +02:00
3332c27978 Bulk replace header guards to use 2021-10-04 11:32:55 +02:00
84b0dcfea4 Host test fix: renamed Loopback inherited member 2021-10-04 11:32:55 +02:00
e0e65856f0 esp-modem(Docs): Update documentation and minor fixes 2021-10-04 11:32:55 +02:00
28433de4ad Update version to 0.1.7 -- support socket VFS 2021-10-04 11:32:55 +02:00
8f17a90026 esp-modem(VFS): Reworked decouple resources from the file system 2021-10-04 11:32:55 +02:00
69ad3ea589 Make the component compatible with IDFv4.1, v4.2, v4.3 2021-10-04 11:32:55 +02:00
a67d74999e Bump the version and upload the component 2021-10-04 11:32:55 +02:00
ab93c13823 Updated per review comments 2021-10-04 11:32:55 +02:00
254 changed files with 20867 additions and 1489 deletions

36
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: Build
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
idf_ver: ["latest", "release-v4.1", "release-v4.2", "release-v4.3", "release-v4.4"]
example: ["pppos_client", "modem_console", "ap_to_pppos", "simple_cmux_client"]
idf_target: ["esp32"]
exclude:
- idf_ver: "release-v4.1"
example: modem_console
- idf_ver: "release-v4.1"
example: ap_to_pppos
- idf_ver: "release-v4.1"
example: simple_cmux_client
- idf_ver: "release-v4.2"
example: simple_cmux_client
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@master
with:
path: esp-protocols
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
cd $GITHUB_WORKSPACE/esp-protocols/components/esp_modem/examples/${{ matrix.example }}
idf.py build

View File

@ -0,0 +1,76 @@
name: Build Websockets
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32"]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v1
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
working-directory: components/esp_websocket_client/examples/
run: |
. ${IDF_PATH}/export.sh
cat sdkconfig.ci >> sdkconfig.defaults
idf.py build
- name: Merge binaries
working-directory: components/esp_websocket_client/examples/build
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
esptool.py --chip ${{ matrix.idf_target }} merge_bin --fill-flash-size 4MB -o flash_image.bin @flash_args
- uses: actions/upload-artifact@v2
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: components/esp_websocket_client/examples/build/
if-no-files-found: error
run-target:
name: Run Example Test on target
needs: build
strategy:
fail-fast: false
matrix:
idf_ver: ["latest"]
idf_target: ["esp32"]
runs-on:
- self-hosted
- ESP32-ETHERNET-KIT
container:
image: python:3.7-buster
options: --privileged # Privileged mode has access to serial ports
steps:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v2
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: components/esp_websocket_client/examples/build/
- name: Install Python packages
env:
PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple"
run: |
pip install -r $GITHUB_WORKSPACE/components/esp_websocket_client/examples/requirements.txt
- name: Download Example Test to target
run: python -m esptool --chip ${{ matrix.idf_target }} write_flash 0x0 components/esp_websocket_client/examples/build/flash_image.bin
- name: Run Example Test on target
working-directory: components/esp_websocket_client/examples
run: |
cp sdkconfig.ci sdkconfig.defaults
pytest --log-cli-level DEBUG --junit-xml=./test_app_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}.xml --target=${{ matrix.idf_target }}
- uses: actions/upload-artifact@v2
if: always()
with:
name: examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: examples/*.xml

View File

@ -0,0 +1,35 @@
name: Build mDNS
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32", "esp32s2", "esp32c3"]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@master
with:
path: esp-protocols
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/examples/
cat sdkconfig.ci.eth_def >> sdkconfig.defaults
idf.py build
rm sdkconfig.defaults
cat sdkconfig.ci.eth_custom_netif >> sdkconfig.defaults
idf.py build
rm sdkconfig.defaults
cat sdkconfig.ci.eth_socket >> sdkconfig.defaults
idf.py build
cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/tests/test_apps/
idf.py build

44
.github/workflows/host-test.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: Host test
on: [push, pull_request]
jobs:
host_test:
name: Build and test
runs-on: ubuntu-20.04
container: espressif/idf:release-v4.3
env:
lwip: lwip-2.1.2
lwip_contrib: contrib-2.1.0
lwip_uri: http://download.savannah.nongnu.org/releases/lwip
steps:
- name: Checkout esp-protocols
uses: actions/checkout@master
with:
path: esp-protocols
- name: Build and Test
shell: bash
run: |
apt-get update && apt-get install -y gcc-8 g++-8
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8
export LWIP_PATH=`pwd`/${{ env.lwip }}
export LWIP_CONTRIB_PATH=`pwd`/${{ env.lwip_contrib }}
wget --no-verbose ${lwip_uri}/${lwip}.zip
unzip -oq ${lwip}.zip
wget --no-verbose ${lwip_uri}/${lwip_contrib}.zip
unzip -oq ${lwip_contrib}.zip
. ${IDF_PATH}/export.sh
cd $GITHUB_WORKSPACE/esp-protocols/components/esp_modem/examples/linux_modem
idf.py build
cd $GITHUB_WORKSPACE/esp-protocols/components/esp_modem/test/host_test
idf.py build
./build/host_modem_test.elf -r junit -o junit.xml
- name: Publish Results
uses: EnricoMi/publish-unit-test-result-action@v1
if: always()
with:
files: esp-protocols/components/esp_modem/test/host_test/junit.xml

View File

@ -0,0 +1,61 @@
name: Docs and Publish
on:
push:
branches:
- master
jobs:
docs_build:
name: Docs-Build-And-Upload
runs-on: ubuntu-latest
steps:
- name: Checkout esp-protocols
uses: actions/checkout@master
with:
persist-credentials: false
fetch-depth: 0
- name: Generate docs
run: |
sudo apt-get update
sudo apt-get -y install doxygen clang python3-pip
python -m pip install breathe recommonmark esp-docs
cd $GITHUB_WORKSPACE/components/esp_modem/docs
./generate_docs
mkdir -p $GITHUB_WORKSPACE/docs/esp_modem
cp -r html/. $GITHUB_WORKSPACE/docs/esp_modem
cd $GITHUB_WORKSPACE/components/esp_websocket_client/docs
./generate_docs
mkdir -p $GITHUB_WORKSPACE/docs/esp_websocket_client
cp -r html/. $GITHUB_WORKSPACE/docs/esp_websocket_client
cd $GITHUB_WORKSPACE/components/mdns/docs
./generate_docs
mkdir -p $GITHUB_WORKSPACE/docs/mdns/en
mkdir -p $GITHUB_WORKSPACE/docs/mdns/zh_CN
cp -r html_en/. $GITHUB_WORKSPACE/docs/mdns/en
cp -r html_zh_CN/. $GITHUB_WORKSPACE/docs/mdns/zh_CN
cd $GITHUB_WORKSPACE/docs
touch .nojekyll
echo '<a href="esp_modem/index.html">esp-modem</a><br>' > index.html
echo '<a href="esp_websocket_client/index.html">esp-websocket-client</a><br>' >> index.html
echo '<a href="mdns/en/index.html">mDNS_en</a><br>' >> index.html
echo '<a href="mdns/zh_CN/index.html">mDNS_zh_CN</a><br>' >> index.html
- name: Upload components to component service
uses: espressif/github-actions/upload_components@master
with:
directories: "components/esp_modem;components/esp_websocket_client;components/mdns"
namespace: "espressif"
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}
- name: Deploy generated docs
uses: JamesIves/github-pages-deploy-action@4.1.5
with:
branch: gh-pages
folder: docs

21
.github/workflows/sync_issues.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: Sync issue comments to JIRA
# This workflow will be triggered when new issue is created
# or a new issue/PR comment is created
on: [issues, issue_comment]
jobs:
sync_issue_comments_to_jira:
name: Sync Issue Comments to Jira
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Sync issue comments to JIRA
uses: espressif/github-actions/sync_issues_to_jira@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JIRA_PASS: ${{ secrets.JIRA_PASS }}
JIRA_PROJECT: IDFGH
JIRA_COMPONENT: esp-protocols
JIRA_URL: ${{ secrets.JIRA_URL }}
JIRA_USER: ${{ secrets.JIRA_USER }}

30
.github/workflows/test_afl_fuzzer.yml vendored Normal file
View File

@ -0,0 +1,30 @@
name: AFL fuzzer compilation test
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32"]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@master
with:
path: esp-protocols
- name: Install Necessary Libs
run: |
apt-get update -y
apt-get install -y libbsd-dev
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/tests/test_afl_fuzz_host/
make INSTR=off

View File

@ -1 +1,21 @@
# Collection of components for ESP-IDF
# Collection of protocol components for ESP-IDF
[Documentation of esp-protocol](https://espressif.github.io/esp-protocols)
## Components
### esp_modem
* Brief introduction [README](components/esp_modem/README.md)
* Full html [documentation](https://espressif.github.io/esp-protocols/esp_modem/index.html)
### mDNS
* Brief introduction [README](components/mdns/README.md)
* Full html [documentation(English)](https://espressif.github.io/esp-protocols/mdns/en/index.html)
* Full html [documentation(Chinese)](https://espressif.github.io/esp-protocols/mdns/zh_CN/index.html)
### esp_websocket_client
* Brief introduction [README](components/esp_websocket_client/README.md)
* Full html [documentation](https://espressif.github.io/esp-protocols/esp_websocket_client/index.html)

View File

@ -0,0 +1,4 @@
idf_component_register(SRCS "connect.c" "stdin_out.c" "addr_from_stdin.c"
INCLUDE_DIRS "include"
PRIV_REQUIRES esp_netif driver
)

View File

@ -0,0 +1,322 @@
menu "Example Connection Configuration"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config EXAMPLE_CONNECT_WIFI
bool "connect using WiFi interface"
default y
help
Protocol examples can use Wi-Fi and/or Ethernet to connect to the network.
Choose this option to connect with WiFi
if EXAMPLE_CONNECT_WIFI
config EXAMPLE_WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config EXAMPLE_WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
choice EXAMPLE_WIFI_SCAN_METHOD
prompt "WiFi Scan Method"
default EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
help
WiFi scan method:
If "Fast" is selected, scan will end after find SSID match AP.
If "All Channel" is selected, scan will end after scan all the channel.
config EXAMPLE_WIFI_SCAN_METHOD_FAST
bool "Fast"
config EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
bool "All Channel"
endchoice
menu "WiFi Scan threshold"
config EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD
int "WiFi minimum rssi"
range -127 0
default -127
help
The minimum rssi to accept in the scan mode.
choice EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD
prompt "WiFi Scan auth mode threshold"
default EXAMPLE_WIFI_AUTH_OPEN
help
The weakest authmode to accept in the scan mode.
config EXAMPLE_WIFI_AUTH_OPEN
bool "OPEN"
config EXAMPLE_WIFI_AUTH_WEP
bool "WEP"
config EXAMPLE_WIFI_AUTH_WPA_PSK
bool "WPA PSK"
config EXAMPLE_WIFI_AUTH_WPA2_PSK
bool "WPA2 PSK"
config EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK
bool "WPA WPA2 PSK"
config EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE
bool "WPA2 ENTERPRISE"
config EXAMPLE_WIFI_AUTH_WPA3_PSK
bool "WPA3 PSK"
config EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK
bool "WPA2 WPA3 PSK"
config EXAMPLE_WIFI_AUTH_WAPI_PSK
bool "WAPI PSK"
endchoice
endmenu
choice EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD
prompt "WiFi Connect AP Sort Method"
default EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
help
WiFi connect AP sort method:
If "Signal" is selected, Sort matched APs in scan list by RSSI.
If "Security" is selected, Sort matched APs in scan list by security mode.
config EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
bool "Signal"
config EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY
bool "Security"
endchoice
endif
config EXAMPLE_CONNECT_ETHERNET
bool "connect using Ethernet interface"
default n
help
Protocol examples can use Wi-Fi and/or Ethernet to connect to the network.
Choose this option to connect with Ethernet
if EXAMPLE_CONNECT_ETHERNET
config EXAMPLE_USE_SPI_ETHERNET
bool
choice EXAMPLE_ETHERNET_TYPE
prompt "Ethernet Type"
default EXAMPLE_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32
default EXAMPLE_USE_W5500
help
Select which kind of Ethernet will be used in the example.
config EXAMPLE_USE_INTERNAL_ETHERNET
depends on IDF_TARGET_ESP32
select ETH_USE_ESP32_EMAC
bool "Internal EMAC"
help
Select internal Ethernet MAC controller.
config EXAMPLE_USE_DM9051
bool "DM9051 Module"
select EXAMPLE_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_DM9051
help
Select external SPI-Ethernet module.
config EXAMPLE_USE_W5500
bool "W5500 Module"
select EXAMPLE_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_W5500
help
Select external SPI-Ethernet module (W5500).
config EXAMPLE_USE_OPENETH
bool "OpenCores Ethernet MAC (EXPERIMENTAL)"
select ETH_USE_OPENETH
help
When this option is enabled, the example is built with support for
OpenCores Ethernet MAC, which allows testing the example in QEMU.
Note that this option is used for internal testing purposes, and
not officially supported. Examples built with this option enabled
will not run on a real ESP32 chip.
endchoice # EXAMPLE_ETHERNET_TYPE
if EXAMPLE_USE_INTERNAL_ETHERNET
choice EXAMPLE_ETH_PHY_MODEL
prompt "Ethernet PHY Device"
default EXAMPLE_ETH_PHY_IP101
help
Select the Ethernet PHY device to use in the example.
config EXAMPLE_ETH_PHY_IP101
bool "IP101"
help
IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver.
Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it.
config EXAMPLE_ETH_PHY_RTL8201
bool "RTL8201/SR8201"
help
RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
config EXAMPLE_ETH_PHY_LAN87XX
bool "LAN87xx"
help
Below chips are supported:
LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
with HP Auto-MDIX and flexPWR® Technology.
LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
Goto https://www.microchip.com for more information about them.
config EXAMPLE_ETH_PHY_DP83848
bool "DP83848"
help
DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver.
Goto http://www.ti.com/product/DP83848J for more information about it.
config EXAMPLE_ETH_PHY_KSZ80XX
bool "KSZ80xx"
help
With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX
Ethernet Physical Layer Tranceivers (PHY).
The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041,
KSZ8051, KSZ8061, KSZ8081, KSZ8091
Goto https://www.microchip.com for more information about them.
endchoice
config EXAMPLE_ETH_MDC_GPIO
int "SMI MDC GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 23
help
Set the GPIO number used by SMI MDC.
config EXAMPLE_ETH_MDIO_GPIO
int "SMI MDIO GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 18
help
Set the GPIO number used by SMI MDIO.
endif
if EXAMPLE_USE_SPI_ETHERNET
config EXAMPLE_ETH_SPI_HOST
int "SPI Host Number"
range 0 2
default 1
help
Set the SPI host used to communicate with the SPI Ethernet Controller.
config EXAMPLE_ETH_SPI_SCLK_GPIO
int "SPI SCLK GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 14
help
Set the GPIO number used by SPI SCLK.
config EXAMPLE_ETH_SPI_MOSI_GPIO
int "SPI MOSI GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 13
help
Set the GPIO number used by SPI MOSI.
config EXAMPLE_ETH_SPI_MISO_GPIO
int "SPI MISO GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 12
help
Set the GPIO number used by SPI MISO.
config EXAMPLE_ETH_SPI_CS_GPIO
int "SPI CS GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 15
help
Set the GPIO number used by SPI CS.
config EXAMPLE_ETH_SPI_CLOCK_MHZ
int "SPI clock speed (MHz)"
range 5 80
default 36
help
Set the clock speed (MHz) of SPI interface.
config EXAMPLE_ETH_SPI_INT_GPIO
int "Interrupt GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 4
help
Set the GPIO number used by the SPI Ethernet module interrupt line.
endif # EXAMPLE_USE_SPI_ETHERNET
config EXAMPLE_ETH_PHY_RST_GPIO
int "PHY Reset GPIO number"
range -1 ENV_GPIO_OUT_RANGE_MAX
default 5
help
Set the GPIO number used to reset PHY chip.
Set to -1 to disable PHY chip hardware reset.
config EXAMPLE_ETH_PHY_ADDR
int "PHY Address"
range 0 31 if EXAMPLE_USE_INTERNAL_ETHERNET
default 1
help
Set PHY address according your board schematic.
endif # EXAMPLE_CONNECT_ETHERNET
config EXAMPLE_CONNECT_IPV6
bool "Obtain IPv6 address"
default y
depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET
select LWIP_IPV6
help
By default, examples will wait until IPv4 and IPv6 local link addresses are obtained.
Disable this option if the network does not support IPv6.
Choose the preferred IPv6 address type if the connection code should wait until other than
the local link address gets assigned.
Consider enabling IPv6 stateless address autoconfiguration (SLAAC) in the LWIP component.
if EXAMPLE_CONNECT_IPV6
choice EXAMPLE_CONNECT_PREFERRED_IPV6
prompt "Preferred IPv6 Type"
default EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK
help
Select which kind of IPv6 address the connect logic waits for.
config EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK
bool "Local Link Address"
help
Blocks until Local link address assigned.
config EXAMPLE_CONNECT_IPV6_PREF_GLOBAL
bool "Global Address"
help
Blocks until Global address assigned.
config EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL
bool "Site Local Address"
help
Blocks until Site link address assigned.
config EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL
bool "Unique Local Link Address"
help
Blocks until Unique local address assigned.
endchoice
endif
endmenu

View File

@ -0,0 +1,68 @@
#include <string.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
#include "lwip/sockets.h"
#include <lwip/netdb.h>
#include <arpa/inet.h>
#define HOST_IP_SIZE 128
esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *addr_family, struct sockaddr_storage *dest_addr)
{
char host_ip[HOST_IP_SIZE];
int len;
static bool already_init = false;
// this function could be called multiple times -> make sure UART init runs only once
if (!already_init) {
example_configure_stdin_stdout();
already_init = true;
}
// ignore empty or LF only string (could receive from DUT class)
do {
fgets(host_ip, HOST_IP_SIZE, stdin);
len = strlen(host_ip);
} while (len<=1 && host_ip[0] == '\n');
host_ip[len - 1] = '\0';
struct addrinfo hints, *addr_list, *cur;
memset( &hints, 0, sizeof( hints ) );
// run getaddrinfo() to decide on the IP protocol
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = sock_type;
hints.ai_protocol = IPPROTO_TCP;
if( getaddrinfo( host_ip, NULL, &hints, &addr_list ) != 0 ) {
return ESP_FAIL;
}
for( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
memcpy(dest_addr, cur->ai_addr, sizeof(*dest_addr));
if (cur->ai_family == AF_INET) {
*ip_protocol = IPPROTO_IP;
*addr_family = AF_INET;
// add port number and return on first IPv4 match
((struct sockaddr_in*)dest_addr)->sin_port = htons(port);
freeaddrinfo( addr_list );
return ESP_OK;
}
#if CONFIG_LWIP_IPV6
else if (cur->ai_family == AF_INET6) {
*ip_protocol = IPPROTO_IPV6;
*addr_family = AF_INET6;
// add port and interface number and return on first IPv6 match
((struct sockaddr_in6*)dest_addr)->sin6_port = htons(port);
((struct sockaddr_in6*)dest_addr)->sin6_scope_id = esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE);
freeaddrinfo( addr_list );
return ESP_OK;
}
#endif
}
// no match found
freeaddrinfo( addr_list );
return ESP_FAIL;
}

View File

@ -0,0 +1,515 @@
/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "protocol_examples_common.h"
#include "sdkconfig.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "esp_wifi_default.h"
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
#include "esp_eth.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif // CONFIG_ETH_USE_SPI_ETHERNET
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
#include "esp_log.h"
#include "esp_netif.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
#define MAX_IP6_ADDRS_PER_NETIF (5)
#define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (s_active_interfaces*2)
#if defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK)
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_LINK_LOCAL
#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL)
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_GLOBAL
#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL)
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_SITE_LOCAL
#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL)
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_UNIQUE_LOCAL
#endif // if-elif CONFIG_EXAMPLE_CONNECT_IPV6_PREF_...
#else
#define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (s_active_interfaces)
#endif
#define EXAMPLE_DO_CONNECT CONFIG_EXAMPLE_CONNECT_WIFI || CONFIG_EXAMPLE_CONNECT_ETHERNET
#if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST
#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN
#elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
#define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN
#endif
#if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
#elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY
#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY
#endif
#if CONFIG_EXAMPLE_WIFI_AUTH_OPEN
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
#elif CONFIG_EXAMPLE_WIFI_AUTH_WEP
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
#elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
#endif
static int s_active_interfaces = 0;
static SemaphoreHandle_t s_semph_get_ip_addrs;
static esp_netif_t *s_example_esp_netif = NULL;
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
static esp_ip6_addr_t s_ipv6_addr;
/* types of ipv6 addresses to be displayed on ipv6 events */
static const char *s_ipv6_addr_types[] = {
"ESP_IP6_ADDR_IS_UNKNOWN",
"ESP_IP6_ADDR_IS_GLOBAL",
"ESP_IP6_ADDR_IS_LINK_LOCAL",
"ESP_IP6_ADDR_IS_SITE_LOCAL",
"ESP_IP6_ADDR_IS_UNIQUE_LOCAL",
"ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6"
};
#endif
static const char *TAG = "example_connect";
#if CONFIG_EXAMPLE_CONNECT_WIFI
static esp_netif_t *wifi_start(void);
static void wifi_stop(void);
#endif
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
static esp_netif_t *eth_start(void);
static void eth_stop(void);
#endif
/**
* @brief Checks the netif description if it contains specified prefix.
* All netifs created withing common connect component are prefixed with the module TAG,
* so it returns true if the specified netif is owned by this module
*/
static bool is_our_netif(const char *prefix, esp_netif_t *netif)
{
return strncmp(prefix, esp_netif_get_desc(netif), strlen(prefix) - 1) == 0;
}
/* set up connection, Wi-Fi and/or Ethernet */
static void start(void)
{
#if CONFIG_EXAMPLE_CONNECT_WIFI
s_example_esp_netif = wifi_start();
s_active_interfaces++;
#endif
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
s_example_esp_netif = eth_start();
s_active_interfaces++;
#endif
#if CONFIG_EXAMPLE_CONNECT_WIFI && CONFIG_EXAMPLE_CONNECT_ETHERNET
/* if both intefaces at once, clear out to indicate that multiple netifs are active */
s_example_esp_netif = NULL;
#endif
#if EXAMPLE_DO_CONNECT
/* create semaphore if at least one interface is active */
s_semph_get_ip_addrs = xSemaphoreCreateCounting(NR_OF_IP_ADDRESSES_TO_WAIT_FOR, 0);
#endif
}
/* tear down connection, release resources */
static void stop(void)
{
#if CONFIG_EXAMPLE_CONNECT_WIFI
wifi_stop();
s_active_interfaces--;
#endif
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
eth_stop();
s_active_interfaces--;
#endif
}
#if EXAMPLE_DO_CONNECT
static esp_ip4_addr_t s_ip_addr;
static void on_got_ip(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
if (!is_our_netif(TAG, event->esp_netif)) {
ESP_LOGW(TAG, "Got IPv4 from another interface \"%s\": ignored", esp_netif_get_desc(event->esp_netif));
return;
}
ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
memcpy(&s_ip_addr, &event->ip_info.ip, sizeof(s_ip_addr));
xSemaphoreGive(s_semph_get_ip_addrs);
}
#endif
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
static void on_got_ipv6(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
if (!is_our_netif(TAG, event->esp_netif)) {
ESP_LOGW(TAG, "Got IPv6 from another netif: ignored");
return;
}
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip);
ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif),
IPV62STR(event->ip6_info.ip), s_ipv6_addr_types[ipv6_type]);
if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) {
memcpy(&s_ipv6_addr, &event->ip6_info.ip, sizeof(s_ipv6_addr));
xSemaphoreGive(s_semph_get_ip_addrs);
}
}
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
esp_err_t example_connect(void)
{
#if EXAMPLE_DO_CONNECT
if (s_semph_get_ip_addrs != NULL) {
return ESP_ERR_INVALID_STATE;
}
#endif
start();
ESP_ERROR_CHECK(esp_register_shutdown_handler(&stop));
ESP_LOGI(TAG, "Waiting for IP(s)");
for (int i = 0; i < NR_OF_IP_ADDRESSES_TO_WAIT_FOR; ++i) {
xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY);
}
// iterate over active interfaces, and print out IPs of "our" netifs
esp_netif_t *netif = NULL;
esp_netif_ip_info_t ip;
for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) {
netif = esp_netif_next(netif);
if (is_our_netif(TAG, netif)) {
ESP_LOGI(TAG, "Connected to %s", esp_netif_get_desc(netif));
ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip));
ESP_LOGI(TAG, "- IPv4 address: " IPSTR, IP2STR(&ip.ip));
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
esp_ip6_addr_t ip6[MAX_IP6_ADDRS_PER_NETIF];
int ip6_addrs = esp_netif_get_all_ip6(netif, ip6);
for (int j = 0; j < ip6_addrs; ++j) {
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j]));
ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(ip6[j]), s_ipv6_addr_types[ipv6_type]);
}
#endif
}
}
return ESP_OK;
}
esp_err_t example_disconnect(void)
{
if (s_semph_get_ip_addrs == NULL) {
return ESP_ERR_INVALID_STATE;
}
vSemaphoreDelete(s_semph_get_ip_addrs);
s_semph_get_ip_addrs = NULL;
stop();
ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&stop));
return ESP_OK;
}
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
static void on_wifi_disconnect(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect...");
esp_err_t err = esp_wifi_connect();
if (err == ESP_ERR_WIFI_NOT_STARTED) {
return;
}
ESP_ERROR_CHECK(err);
}
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
static void on_wifi_connect(void *esp_netif, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
esp_netif_create_ip6_linklocal(esp_netif);
}
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
static esp_netif_t *wifi_start(void)
{
char *desc;
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA();
// Prefix the interface description with the module TAG
// Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask)
asprintf(&desc, "%s: %s", TAG, esp_netif_config.if_desc);
esp_netif_config.if_desc = desc;
esp_netif_config.route_prio = 128;
esp_netif_t *netif = esp_netif_create_wifi(WIFI_IF_STA, &esp_netif_config);
free(desc);
esp_wifi_set_default_wifi_sta_handlers();
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, NULL));
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect, netif));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
#endif
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_EXAMPLE_WIFI_SSID,
.password = CONFIG_EXAMPLE_WIFI_PASSWORD,
.scan_method = EXAMPLE_WIFI_SCAN_METHOD,
.sort_method = EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD,
.threshold.rssi = CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD,
.threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD,
},
};
ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
esp_wifi_connect();
return netif;
}
static void wifi_stop(void)
{
esp_netif_t *wifi_netif = get_example_netif_from_desc("sta");
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect));
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip));
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect));
#endif
esp_err_t err = esp_wifi_stop();
if (err == ESP_ERR_WIFI_NOT_INIT) {
return;
}
ESP_ERROR_CHECK(err);
ESP_ERROR_CHECK(esp_wifi_deinit());
ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(wifi_netif));
esp_netif_destroy(wifi_netif);
s_example_esp_netif = NULL;
}
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
/** Event handler for Ethernet events */
static void on_eth_event(void *esp_netif, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
ESP_LOGI(TAG, "Ethernet Link Up");
ESP_ERROR_CHECK(esp_netif_create_ip6_linklocal(esp_netif));
break;
default:
break;
}
}
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
static esp_eth_handle_t s_eth_handle = NULL;
static esp_eth_mac_t *s_mac = NULL;
static esp_eth_phy_t *s_phy = NULL;
static esp_eth_netif_glue_handle_t s_eth_glue = NULL;
static esp_netif_t *eth_start(void)
{
char *desc;
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
// Prefix the interface description with the module TAG
// Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask)
asprintf(&desc, "%s: %s", TAG, esp_netif_config.if_desc);
esp_netif_config.if_desc = desc;
esp_netif_config.route_prio = 64;
esp_netif_config_t netif_config = {
.base = &esp_netif_config,
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
};
esp_netif_t *netif = esp_netif_new(&netif_config);
assert(netif);
free(desc);
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR;
phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO;
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
#if CONFIG_EXAMPLE_ETH_PHY_IP101
s_phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
s_phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
s_phy = esp_eth_phy_new_lan87xx(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_DP83848
s_phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX
s_phy = esp_eth_phy_new_ksz80xx(&phy_config);
#endif
#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET
gpio_install_isr_service(0);
spi_device_handle_t spi_handle = NULL;
spi_bus_config_t buscfg = {
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1));
#if CONFIG_EXAMPLE_USE_DM9051
spi_device_interface_config_t devcfg = {
.command_bits = 1,
.address_bits = 7,
.mode = 0,
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
.queue_size = 20
};
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
/* dm9051 ethernet driver is based on spi driver */
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
dm9051_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
s_mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
s_phy = esp_eth_phy_new_dm9051(&phy_config);
#elif CONFIG_EXAMPLE_USE_W5500
spi_device_interface_config_t devcfg = {
.command_bits = 16, // Actually it's the address phase in W5500 SPI frame
.address_bits = 8, // Actually it's the control phase in W5500 SPI frame
.mode = 0,
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
.queue_size = 20
};
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
/* w5500 ethernet driver is based on spi driver */
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
w5500_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
s_mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
s_phy = esp_eth_phy_new_w5500(&phy_config);
#endif
#elif CONFIG_EXAMPLE_USE_OPENETH
phy_config.autonego_timeout_ms = 100;
s_mac = esp_eth_mac_new_openeth(&mac_config);
s_phy = esp_eth_phy_new_dp83848(&phy_config);
#endif
// Install Ethernet driver
esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy);
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle));
#if !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
/* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually.
02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control.
*/
ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) {
0x02, 0x00, 0x00, 0x12, 0x34, 0x56
}));
#endif
// combine driver with netif
s_eth_glue = esp_eth_new_netif_glue(s_eth_handle);
esp_netif_attach(netif, s_eth_glue);
// Register user defined event handers
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip, NULL));
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
#endif
esp_eth_start(s_eth_handle);
return netif;
}
static void eth_stop(void)
{
esp_netif_t *eth_netif = get_example_netif_from_desc("eth");
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip));
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event));
#endif
ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle));
ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue));
ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle));
s_eth_handle = NULL;
ESP_ERROR_CHECK(s_phy->del(s_phy));
ESP_ERROR_CHECK(s_mac->del(s_mac));
esp_netif_destroy(eth_netif);
s_example_esp_netif = NULL;
}
esp_eth_handle_t get_example_eth_handle(void)
{
return s_eth_handle;
}
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
esp_netif_t *get_example_netif(void)
{
return s_example_esp_netif;
}
esp_netif_t *get_example_netif_from_desc(const char *desc)
{
esp_netif_t *netif = NULL;
char *expected_desc;
asprintf(&expected_desc, "%s: %s", TAG, desc);
while ((netif = esp_netif_next(netif)) != NULL) {
if (strcmp(esp_netif_get_desc(netif), expected_desc) == 0) {
free(expected_desc);
return netif;
}
}
free(expected_desc);
return netif;
}

View File

@ -0,0 +1,44 @@
/* Common utilities for socket address input interface:
The API get_addr_from_stdin() is mainly used by socket client examples which read IP address from stdin (if configured).
This option is typically used in the CI, but could be enabled in the project configuration.
In that case this component is used to receive a string that is evaluated and processed to output
socket structures to open a connectio
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include <arpa/inet.h>
/**
* @brief Read and evaluate IP address from stdin
*
* This API reads stdin and parses the input address using getaddrinfo()
* to fill in struct sockaddr_storage (for both IPv4 and IPv6) used to open
* a socket. IP protocol is guessed from the IP address string.
*
* @param[in] port port number of expected connection
* @param[in] sock_type expected protocol: SOCK_STREAM or SOCK_DGRAM
* @param[out] ip_protocol resultant IP protocol: IPPROTO_IP or IPPROTO_IP6
* @param[out] addr_family resultant address family: AF_INET or AF_INET6
* @param[out] dest_addr sockaddr_storage structure (for both IPv4 and IPv6)
* @return ESP_OK on success, ESP_FAIL otherwise
*/
esp_err_t get_addr_from_stdin(int port, int sock_type,
int *ip_protocol,
int *addr_family,
struct sockaddr_storage *dest_addr);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,92 @@
/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_err.h"
#include "esp_netif.h"
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
#define EXAMPLE_INTERFACE get_example_netif()
#endif
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
#define EXAMPLE_INTERFACE get_example_netif()
#endif
#if !defined (CONFIG_EXAMPLE_CONNECT_ETHERNET) && !defined (CONFIG_EXAMPLE_CONNECT_WIFI)
// This is useful for some tests which do not need a network connection
#define EXAMPLE_INTERFACE NULL
#endif
/**
* @brief Configure Wi-Fi or Ethernet, connect, wait for IP
*
* This all-in-one helper function is used in protocols examples to
* reduce the amount of boilerplate in the example.
*
* It is not intended to be used in real world applications.
* See examples under examples/wifi/getting_started/ and examples/ethernet/
* for more complete Wi-Fi or Ethernet initialization code.
*
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*
* @return ESP_OK on successful connection
*/
esp_err_t example_connect(void);
/**
* Counterpart to example_connect, de-initializes Wi-Fi or Ethernet
*/
esp_err_t example_disconnect(void);
/**
* @brief Configure stdin and stdout to use blocking I/O
*
* This helper function is used in ASIO examples. It wraps installing the
* UART driver and configuring VFS layer to use UART driver for console I/O.
*/
esp_err_t example_configure_stdin_stdout(void);
/**
* @brief Returns esp-netif pointer created by example_connect()
*
* @note If multiple interfaces active at once, this API return NULL
* In that case the get_example_netif_from_desc() should be used
* to get esp-netif pointer based on interface description
*/
esp_netif_t *get_example_netif(void);
/**
* @brief Returns esp-netif pointer created by example_connect() described by
* the supplied desc field
*
* @param desc Textual interface of created network interface, for example "sta"
* indicate default WiFi station, "eth" default Ethernet interface.
*
*/
esp_netif_t *get_example_netif_from_desc(const char *desc);
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
/**
* @brief Get the example Ethernet driver handle
*
* @return esp_eth_handle_t
*/
esp_eth_handle_t get_example_eth_handle(void);
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,29 @@
/* Common functions for protocol examples, to configure stdin and stdout.
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "protocol_examples_common.h"
#include "esp_err.h"
#include "esp_vfs_dev.h"
#include "driver/uart.h"
#include "sdkconfig.h"
esp_err_t example_configure_stdin_stdout(void)
{
// Initialize VFS & UART so we can use std::cout/cin
setvbuf(stdin, NULL, _IONBF, 0);
/* Install UART driver for interrupt-driven reads and writes */
ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM,
256, 0, 0, NULL, 0) );
/* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
return ESP_OK;
}

View File

@ -51,9 +51,9 @@ tools/unit-test-app/test_configs
log_ut_cmake
# test application build files
tools/test_apps/**/build
tools/test_apps/**/sdkconfig
tools/test_apps/**/sdkconfig.old
test/**/build
test/**/sdkconfig
test/**/sdkconfig.old
# IDF monitor test
tools/test_idf_monitor/outputs
@ -88,3 +88,6 @@ build
# lock files for examples and components
dependencies.lock
# ignore generated docs
docs/html

View File

@ -7,6 +7,7 @@ if(${target} STREQUAL "linux")
set(dependencies esp_system_protocols_linux)
else()
set(platform_srcs src/esp_modem_primitives_freertos.cpp
src/esp_modem_api_target.cpp
src/esp_modem_uart.cpp
src/esp_modem_term_uart.cpp
src/esp_modem_netif.cpp)
@ -22,6 +23,8 @@ set(srcs ${platform_srcs}
"src/esp_modem_cmux.cpp"
"src/esp_modem_command_library.cpp"
"src/esp_modem_term_fs.cpp"
"src/esp_modem_vfs_uart_creator.cpp"
"src/esp_modem_vfs_socket_creator.cpp"
"src/esp_modem_modules.cpp")
set(include_dirs "include")
@ -31,7 +34,11 @@ idf_component_register(SRCS "${srcs}"
PRIV_INCLUDE_DIRS private_include
REQUIRES ${dependencies})
target_compile_features(${COMPONENT_LIB} PRIVATE cxx_std_17)
set_target_properties(${COMPONENT_LIB} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS ON
)
if(${target} STREQUAL "linux")
# This is needed for ESP_LOGx() macros, as integer formats differ on ESP32(..) and x64

View File

@ -1,6 +1,6 @@
# ESP MODEM
The `esp-modem` component is a managed component for `esp-idf` that could be used for communication with GSM/LTE modems
The `esp-modem` component is a managed component for `esp-idf` that is used for communication with GSM/LTE modems
that support AT commands and PPP protocol as a network interface.
## Examples
@ -16,4 +16,4 @@ Get started with one of the examples:
## Documentation
* Continue with esp-modem [brief overview](docs/README.md)
* View the full [html documentation ](docs/html/index.html)
* View the full [html documentation](https://espressif.github.io/esp-protocols/esp_modem/index.html)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -36,11 +36,11 @@ After the object is created, the application interaction with the DCE is in
* switching between data and command mode
### DTE
Is an abstraction of the connected interface. Current implementation supports only UART
Is an abstraction of the physical interface connected to the modem. Current implementation supports only UART
### PPP
### PPP netif
Is used to connect the specific network interface to the modem data mode. Currently implementation supports only PPPoS protocol.
Is used to attach the specific network interface to a network communication protocol used by the modem. Currently implementation supports only PPPoS protocol.
### Module
@ -48,7 +48,7 @@ Abstraction of the specific modem device. Currently the component supports SIM80
## Use cases
Users could interact with the esp-modem using the DCE's interface, to basically
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)
@ -57,16 +57,15 @@ 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 modules 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.
* `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 the data mode, while other to command mode.
after creating multiple virtual terminals, designating some of them solely to data mode, others solely to command mode.
### DTE's
@ -74,6 +73,6 @@ Currently we support only UART, but modern modules support other communication i
### Other devices
Adding a new device is a must-have requirement for the esp-component. Different modules support different commands,
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.

View File

@ -19,14 +19,15 @@ 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:`GenericModule`. In order to instantiate
the appropriate DCE of this module, application could use :ref:`the DCE factory<dce_factory>`, but build the DCE with
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.
@ -41,7 +42,7 @@ 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 can communicate on the custom interface. This terminal should support basic IO methods defined in :cpp:class:`esp_modem::Terminal` and derive from it.
- 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.

View File

@ -1,15 +1,15 @@
.. _c_api:
API Guide for C interface
=========================
C API Documentation
===================
C API is very simple and consist of these two basic parts:
The C API is very simple and consist of these two basic parts:
- :ref:`lifecycle_api`
- :ref:`modem_commands`
Typical application workflow is to:
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`)
@ -41,6 +41,9 @@ 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

View File

@ -16,7 +16,8 @@ copyright = u'2016 - 2021, Espressif Systems (Shanghai) Co., Ltd'
# for a list of supported languages.
language = 'en'
extensions = ['breathe']
extensions = ['breathe', 'recommonmark']
breathe_projects = {'esp_modem': 'xml'}

View File

@ -1,25 +0,0 @@
- :cpp:func:`esp_modem::DCE::sync`
- :cpp:func:`esp_modem::DCE::get_operator_name`
- :cpp:func:`esp_modem::DCE::store_profile`
- :cpp:func:`esp_modem::DCE::set_pin`
- :cpp:func:`esp_modem::DCE::read_pin`
- :cpp:func:`esp_modem::DCE::set_echo`
- :cpp:func:`esp_modem::DCE::sms_txt_mode`
- :cpp:func:`esp_modem::DCE::sms_character_set`
- :cpp:func:`esp_modem::DCE::send_sms`
- :cpp:func:`esp_modem::DCE::resume_data_mode`
- :cpp:func:`esp_modem::DCE::set_pdp_context`
- :cpp:func:`esp_modem::DCE::set_command_mode`
- :cpp:func:`esp_modem::DCE::set_cmux`
- :cpp:func:`esp_modem::DCE::get_imsi`
- :cpp:func:`esp_modem::DCE::get_imei`
- :cpp:func:`esp_modem::DCE::get_module_name`
- :cpp:func:`esp_modem::DCE::set_data_mode`
- :cpp:func:`esp_modem::DCE::get_signal_quality`
- :cpp:func:`esp_modem::DCE::set_flow_control`
- :cpp:func:`esp_modem::DCE::hang_up`
- :cpp:func:`esp_modem::DCE::get_battery_status`
- :cpp:func:`esp_modem::DCE::power_down`
- :cpp:func:`esp_modem::DCE::reset`
- :cpp:func:`esp_modem::DCE::set_baud`

View File

@ -1,99 +0,0 @@
// cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -CC -xc -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' > c_api.h
// 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
// call parametrs by names for documentation
// --- DCE command documentation starts here ---
/**
* @brief Sends the initial AT sequence to sync up with the device
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_sync (); /**
* @brief Reads the operator name
* @param[out] name module name
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_get_operator_name (char* name); /**
* @brief Stores current user profile
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_store_profile (); /**
* @brief Sets the supplied PIN code
* @param[in] pin Pin
* @return OK, FAIL or TIMEOUT
*/command_result esp_modem_set_pin (const char* pin); /**
* @brief Checks if the SIM needs a PIN
* @param[out] pin_ok true if the SIM card doesn't need a PIN to unlock
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_read_pin (bool* pin_ok); /**
* @brief Sets echo mode
* @param[in] echo_on true if echo mode on (repeats the commands)
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_set_echo (const bool echo_on); /**
* @brief Sets the Txt or Pdu mode for SMS (only txt is supported)
* @param[in] txt true if txt mode
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_sms_txt_mode (const bool txt); /**
* @brief Sets the default (GSM) charater set
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_sms_character_set (); /**
* @brief Sends SMS message in txt mode
* @param[in] number Phone number to send the message to
* @param[in] message Text message to be sent
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_send_sms (const char* number, const char* message); /**
* @brief Resumes data mode (Switches back to th data mode, which was temporarily suspended)
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_resume_data_mode (); /**
* @brief Sets php context
* @param[in] x PdP context struct to setup modem cellular connection
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_set_pdp_context (struct PdpContext* x); /**
* @brief Switches to the command mode
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_set_command_mode (); /**
* @brief Switches to the CMUX mode
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_set_cmux (); /**
* @brief Reads the IMSI number
* @param[out] imsi Module's IMSI number
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_get_imsi (char* imsi); /**
* @brief Reads the IMEI number
* @param[out] imei Module's IMEI number
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_get_imei (char* imei); /**
* @brief Reads the module name
* @param[out] name module name
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_get_module_name (char* name); /**
* @brief Sets the modem to data mode
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_set_data_mode (); /**
* @brief Get Signal quality
* @param[out] rssi signal strength indication
* @param[out] ber channel bit error rate
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_get_signal_quality (int* rssi, int* ber); /**
* @brief Sets HW control flow
* @param[in] dce_flow 0=none, 2=RTS hw flow control of DCE
* @param[in] dte_flow 0=none, 2=CTS hw flow control of DTE
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_set_flow_control (int dce_flow, int dte_flow); /**
* @brief Hangs up current data call
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_hang_up (); /**
* @brief Get voltage levels of modem power up circuitry
* @param[out] voltage Current status in mV
* @param[out] bcs charge status (-1-Not available, 0-Not charging, 1-Charging, 2-Charging done)
* @param[out] bcl 1-100% battery capacity, -1-Not available
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_get_battery_status (int* voltage, int* bcs, int* bcl); /**
* @brief Power down the module
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_power_down (); /**
* @brief Reset the module
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_reset (); /**
* @brief Configures the baudrate
* @param[in] baud Desired baud rate of the DTE
* @return OK, FAIL or TIMEOUT
*/ command_result esp_modem_set_baud (int baud);

View File

@ -1,111 +0,0 @@
// cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -CC -xc -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' > c_api.h
// 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
// call parametrs by names for documentation
// --- DCE command documentation starts here ---
class esp_modem::DCE: public DCE_T<GenericModule> {
public:
using DCE_T<GenericModule>::DCE_T;
/**
* @brief Sends the initial AT sequence to sync up with the device
* @return OK, FAIL or TIMEOUT
*/ command_result sync (); /**
* @brief Reads the operator name
* @param[out] name module name
* @return OK, FAIL or TIMEOUT
*/ command_result get_operator_name (std::string& name); /**
* @brief Stores current user profile
* @return OK, FAIL or TIMEOUT
*/ command_result store_profile (); /**
* @brief Sets the supplied PIN code
* @param[in] pin Pin
* @return OK, FAIL or TIMEOUT
*/command_result set_pin (const std::string& pin); /**
* @brief Checks if the SIM needs a PIN
* @param[out] pin_ok true if the SIM card doesn't need a PIN to unlock
* @return OK, FAIL or TIMEOUT
*/ command_result read_pin (bool& pin_ok); /**
* @brief Sets echo mode
* @param[in] echo_on true if echo mode on (repeats the commands)
* @return OK, FAIL or TIMEOUT
*/ command_result set_echo (const bool echo_on); /**
* @brief Sets the Txt or Pdu mode for SMS (only txt is supported)
* @param[in] txt true if txt mode
* @return OK, FAIL or TIMEOUT
*/ command_result sms_txt_mode (const bool txt); /**
* @brief Sets the default (GSM) charater set
* @return OK, FAIL or TIMEOUT
*/ command_result sms_character_set (); /**
* @brief Sends SMS message in txt mode
* @param[in] number Phone number to send the message to
* @param[in] message Text message to be sent
* @return OK, FAIL or TIMEOUT
*/ command_result send_sms (const std::string& number, const std::string& message); /**
* @brief Resumes data mode (Switches back to th data mode, which was temporarily suspended)
* @return OK, FAIL or TIMEOUT
*/ command_result resume_data_mode (); /**
* @brief Sets php context
* @param[in] x PdP context struct to setup modem cellular connection
* @return OK, FAIL or TIMEOUT
*/ command_result set_pdp_context (PdpContext& x); /**
* @brief Switches to the command mode
* @return OK, FAIL or TIMEOUT
*/ command_result set_command_mode (); /**
* @brief Switches to the CMUX mode
* @return OK, FAIL or TIMEOUT
*/ command_result set_cmux (); /**
* @brief Reads the IMSI number
* @param[out] imsi Module's IMSI number
* @return OK, FAIL or TIMEOUT
*/ command_result get_imsi (std::string& imsi); /**
* @brief Reads the IMEI number
* @param[out] imei Module's IMEI number
* @return OK, FAIL or TIMEOUT
*/ command_result get_imei (std::string& imei); /**
* @brief Reads the module name
* @param[out] name module name
* @return OK, FAIL or TIMEOUT
*/ command_result get_module_name (std::string& name); /**
* @brief Sets the modem to data mode
* @return OK, FAIL or TIMEOUT
*/ command_result set_data_mode (); /**
* @brief Get Signal quality
* @param[out] rssi signal strength indication
* @param[out] ber channel bit error rate
* @return OK, FAIL or TIMEOUT
*/ command_result get_signal_quality (int& rssi, int& ber); /**
* @brief Sets HW control flow
* @param[in] dce_flow 0=none, 2=RTS hw flow control of DCE
* @param[in] dte_flow 0=none, 2=CTS hw flow control of DTE
* @return OK, FAIL or TIMEOUT
*/ command_result set_flow_control (int dce_flow, int dte_flow); /**
* @brief Hangs up current data call
* @return OK, FAIL or TIMEOUT
*/ command_result hang_up (); /**
* @brief Get voltage levels of modem power up circuitry
* @param[out] voltage Current status in mV
* @param[out] bcs charge status (-1-Not available, 0-Not charging, 1-Charging, 2-Charging done)
* @param[out] bcl 1-100% battery capacity, -1-Not available
* @return OK, FAIL or TIMEOUT
*/ command_result get_battery_status (int& voltage, int& bcs, int& bcl); /**
* @brief Power down the module
* @return OK, FAIL or TIMEOUT
*/ command_result power_down (); /**
* @brief Reset the module
* @return OK, FAIL or TIMEOUT
*/ command_result reset (); /**
* @brief Configures the baudrate
* @param[in] baud Desired baud rate of the DTE
* @return OK, FAIL or TIMEOUT
*/ command_result set_baud (int baud);
};

View File

@ -19,5 +19,5 @@ doxygen
# Generate the docs
python -u -m sphinx.cmd.build -b html . html
# Cleanup the doxygen xml's
rm -rf xml
# Cleanup the doxygen xml's and temporary headers
rm -rf xml esp_modem_api_commands.h esp_modem_dce.hpp cxx_api_links.rst

View File

@ -9,6 +9,13 @@ The esp-modem actually implements the DCE class, which in turn aggregates these
- :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
@ -63,6 +70,36 @@ 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
^^^^^^^^^^^^^^^

View File

@ -15,3 +15,7 @@ By default, this example simply connects to the PPP server using a supported dev
This example however, doesn't rely on sending specific AT commands, just the bare minimum to setup the cellular network.
Thus, if the `EXAMPLE_USE_MINIMAL_DCE` option is enabled, we directly inherit from the `ModuleIf` and implement only the basic commands.
Also, to demonstrate the dce_factory functionality, a new `NetDCE_Factory` is implemented for creating the network module and the DCE.
### Supported IDF versions
This example is only supported from `v4.2`, since is uses NAPT feature.

View File

@ -31,9 +31,16 @@ menu "Example Configuration"
help
Set APN (Access Point Name), a logical name to choose data network
config EXAMPLE_NEED_SIM_PIN
bool "SIM PIN needed"
default n
help
Enable to set SIM PIN before starting the example
config EXAMPLE_SIM_PIN
string "Set SIM PIN"
default "1234"
depends on EXAMPLE_NEED_SIM_PIN
help
Pin to unlock the SIM

View File

@ -16,6 +16,10 @@
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "network_dce.h"
#if ESP_IDF_VERSION_MAJOR >= 5
#include "esp_mac.h"
#include "dhcpserver/dhcpserver.h"
#endif
#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
@ -32,36 +36,32 @@ static const int DISCONNECT_BIT = BIT1;
static void on_ip_event(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (event_base == IP_EVENT) {
ESP_LOGD(TAG, "IP event! %d", event_id);
if (event_id == IP_EVENT_PPP_GOT_IP) {
esp_netif_dns_info_t dns_info;
ESP_LOGD(TAG, "IP event! %d", event_id);
if (event_id == IP_EVENT_PPP_GOT_IP) {
esp_netif_dns_info_t dns_info;
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
esp_netif_t *netif = event->esp_netif;
ESP_LOGI(TAG, "Modem Connect to PPP Server");
ESP_LOGI(TAG, "~~~~~~~~~~~~~~");
ESP_LOGI(TAG, "IP : " IPSTR, IP2STR(&event->ip_info.ip));
ESP_LOGI(TAG, "Netmask : " IPSTR, IP2STR(&event->ip_info.netmask));
ESP_LOGI(TAG, "Gateway : " IPSTR, IP2STR(&event->ip_info.gw));
esp_netif_get_dns_info(netif, 0, &dns_info);
ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4));
esp_netif_get_dns_info(netif, 1, &dns_info);
ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4));
ESP_LOGI(TAG, "~~~~~~~~~~~~~~");
xEventGroupSetBits(event_group, CONNECT_BIT);
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
esp_netif_t *netif = event->esp_netif;
ESP_LOGI(TAG, "Modem Connect to PPP Server");
ESP_LOGI(TAG, "~~~~~~~~~~~~~~");
ESP_LOGI(TAG, "IP : " IPSTR, IP2STR(&event->ip_info.ip));
ESP_LOGI(TAG, "Netmask : " IPSTR, IP2STR(&event->ip_info.netmask));
ESP_LOGI(TAG, "Gateway : " IPSTR, IP2STR(&event->ip_info.gw));
esp_netif_get_dns_info(netif, 0, &dns_info);
ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4));
esp_netif_get_dns_info(netif, 1, &dns_info);
ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4));
ESP_LOGI(TAG, "~~~~~~~~~~~~~~");
xEventGroupSetBits(event_group, CONNECT_BIT);
ESP_LOGI(TAG, "GOT ip event!!!");
} else if (event_id == IP_EVENT_PPP_LOST_IP) {
ESP_LOGI(TAG, "Modem Disconnect from PPP Server");
xEventGroupSetBits(event_group, DISCONNECT_BIT);
} else if (event_id == IP_EVENT_GOT_IP6) {
ESP_LOGI(TAG, "GOT IPv6 event!");
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
ESP_LOGI(TAG, "Got IPv6 address " IPV6STR, IPV62STR(event->ip6_info.ip));
}
ESP_LOGI(TAG, "GOT ip event!!!");
} else if (event_id == IP_EVENT_PPP_LOST_IP) {
ESP_LOGI(TAG, "Modem Disconnect from PPP Server");
xEventGroupSetBits(event_group, DISCONNECT_BIT);
} else if (event_id == IP_EVENT_GOT_IP6) {
ESP_LOGI(TAG, "GOT IPv6 event!");
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
ESP_LOGI(TAG, "Got IPv6 address " IPV6STR, IPV62STR(event->ip6_info.ip));
}
}
@ -93,7 +93,6 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base,
void wifi_init_softap(void)
{
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));

View File

@ -25,6 +25,7 @@ esp_err_t modem_init_network(esp_netif_t *netif)
return ESP_FAIL;
}
#ifdef CONFIG_EXAMPLE_NEED_SIM_PIN
// configure the PIN
bool pin_ok = false;
if (esp_modem_read_pin(dce, &pin_ok) == ESP_OK && pin_ok == false) {
@ -34,6 +35,7 @@ esp_err_t modem_init_network(esp_netif_t *netif)
abort();
}
}
#endif // CONFIG_EXAMPLE_NEED_SIM_PIN
return ESP_OK;
}

View File

@ -19,40 +19,28 @@ using namespace esp_modem;
using namespace esp_modem::dce_factory;
class NetModule;
typedef DCE_T<NetModule> NetDCE;
/**
* @brief Local network object used to setup PPP network
*/
class PPPNetwork {
public:
esp_err_t init(esp_netif_t *netif, const std::string& apn, const std::string &pin_number);
void deinit();
NetDCE * get_dce();
private:
NetDCE *dce;
};
using NetDCE = DCE_T<NetModule>;
/**
* @brief The PPP network is a singleton, allocate statically here
*/
static PPPNetwork ppp_network;
/**
* @brief Custom factory for creating NetDCE and NetModule
*/
class NetDCE_Factory: public Factory {
public:
template <typename T, typename ...Args>
static DCE_T<T>* create(const config *cfg, Args&&... args)
template <typename Module, typename ...Args>
static DCE_T<Module> *create(const config *cfg, Args &&... args)
{
return build_generic_DCE<T>(cfg, std::forward<Args>(args)...);
return build_generic_DCE<Module>(cfg, std::forward<Args>(args)...);
}
template <typename T, typename ...Args>
static std::shared_ptr<T> create_module(const config *cfg, Args&&... args)
template <typename Module, typename ...Args>
static std::shared_ptr<Module> create_module(const config *cfg, Args &&... args)
{
return build_shared_module<T>(cfg, std::forward<Args>(args)...);
return build_shared_module<Module>(cfg, std::forward<Args>(args)...);
}
};
@ -65,42 +53,48 @@ public:
class NetModule: public ModuleIf {
public:
explicit NetModule(std::shared_ptr<DTE> dte, const esp_modem_dce_config *cfg):
dte(std::move(dte)), apn(std::string(cfg->apn)) {}
dte(std::move(dte)), apn(std::string(cfg->apn)) {}
bool setup_data_mode() override
[[nodiscard]] bool setup_data_mode() override
{
PdpContext pdp(apn);
if (set_pdp_context(pdp) != command_result::OK)
if (set_pdp_context(pdp) != command_result::OK) {
return false;
}
return true;
}
bool set_mode(modem_mode mode) override
{
if (mode == modem_mode::DATA_MODE) {
if (set_data_mode() != command_result::OK)
switch (mode) {
case esp_modem::modem_mode::DATA_MODE:
if (set_data_mode() != command_result::OK) {
return resume_data_mode() == command_result::OK;
}
return true;
}
if (mode == modem_mode::COMMAND_MODE) {
case esp_modem::modem_mode::COMMAND_MODE:
return set_command_mode() == command_result::OK;
default:
return false;
}
return false;
}
bool init(const std::string& pin)
[[maybe_unused]] bool init_sim(const std::string &pin)
{
// switch to command mode (in case we were in PPP mode)
static_cast<void>(set_command_mode()); // ignore the potential failure, as we might be in command mode after startup
bool is_pin_ok;
if (read_pin(is_pin_ok) != command_result::OK)
if (read_pin(is_pin_ok) != command_result::OK) {
return false;
}
if (!is_pin_ok) {
if (set_pin(pin) != command_result::OK)
if (set_pin(pin) != command_result::OK) {
return false;
}
vTaskDelay(pdMS_TO_TICKS(1000));
if (read_pin(is_pin_ok) != command_result::OK || !is_pin_ok)
if (read_pin(is_pin_ok) != command_result::OK || !is_pin_ok) {
return false;
}
}
return true;
}
@ -109,68 +103,83 @@ private:
std::shared_ptr<DTE> dte;
std::string apn;
[[nodiscard]] command_result set_pdp_context(PdpContext& pdp) { return dce_commands::set_pdp_context(dte.get(),pdp); }
[[nodiscard]] command_result set_pin(const std::string &pin) { return dce_commands::set_pin(dte.get(), pin); }
[[nodiscard]] command_result read_pin(bool& pin_ok) { return dce_commands::read_pin(dte.get(), pin_ok); }
[[nodiscard]] command_result set_data_mode() { return dce_commands::set_data_mode(dte.get()); }
[[nodiscard]] command_result resume_data_mode() { return dce_commands::resume_data_mode(dte.get()); }
[[nodiscard]] command_result set_command_mode() { return dce_commands::set_command_mode(dte.get()); }
[[nodiscard]] command_result set_pdp_context(PdpContext &pdp)
{
return dce_commands::set_pdp_context(dte.get(), pdp);
}
[[nodiscard]] command_result set_pin(const std::string &pin)
{
return dce_commands::set_pin(dte.get(), pin);
}
[[nodiscard]] command_result read_pin(bool &pin_ok)
{
return dce_commands::read_pin(dte.get(), pin_ok);
}
[[nodiscard]] command_result set_data_mode()
{
return dce_commands::set_data_mode(dte.get());
}
[[nodiscard]] command_result resume_data_mode()
{
return dce_commands::resume_data_mode(dte.get());
}
[[nodiscard]] command_result set_command_mode()
{
return dce_commands::set_command_mode(dte.get());
}
};
esp_err_t PPPNetwork::init(esp_netif_t *netif, const std::string& apn, const std::string &pin_number)
/**
* @brief Implement the C-API for the AP-2-PPP functionality
*/
namespace {
/**
* @brief Local network object used to setup PPP network
*/
NetDCE *dce = nullptr;
extern "C" esp_err_t modem_init_network(esp_netif_t *netif)
{
// configure
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
dte_config.uart_config.rx_buffer_size = 16384;
dte_config.uart_config.tx_buffer_size = 2048;
esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(apn.c_str());
esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_PPP_APN);
// create DTE and minimal network DCE
auto uart_dte = create_uart_dte(&dte_config);
// create the specific device (and initialize it)
auto dev = NetDCE_Factory::create_module<NetModule>(&dce_config, uart_dte, netif);
if (!dev->init(pin_number))
#if CONFIG_EXAMPLE_NEED_SIM_PIN == 1
if (!dev->init_sim(CONFIG_EXAMPLE_SIM_PIN)) {
return ESP_FAIL;
}
#endif
// now create the DCE from our already existent device
dce = NetDCE_Factory::create<NetModule>(&dce_config, uart_dte, netif, dev);
if (dce == nullptr)
if (dce == nullptr) {
return ESP_FAIL;
}
return ESP_OK;
}
void PPPNetwork::deinit()
extern "C" void modem_start_network()
{
dce->set_mode(esp_modem::modem_mode::DATA_MODE);
}
extern "C" void modem_stop_network()
{
dce->set_mode(esp_modem::modem_mode::COMMAND_MODE);
}
extern "C" void modem_deinit_network()
{
free(dce);
dce = nullptr;
}
NetDCE *PPPNetwork::get_dce()
{
return dce;
}
/**
* @brief Implement the C-API for the AP-2-PPP functionality
*/
extern "C" esp_err_t modem_init_network(esp_netif_t *netif)
{
return ppp_network.init(netif, CONFIG_EXAMPLE_MODEM_PPP_APN, CONFIG_EXAMPLE_SIM_PIN);
}
extern "C" void modem_start_network()
{
ppp_network.get_dce()->set_mode(esp_modem::modem_mode::DATA_MODE);
}
extern "C" void modem_stop_network()
{
ppp_network.get_dce()->set_mode(esp_modem::modem_mode::COMMAND_MODE);
}
extern "C" void modem_deinit_network()
{
ppp_network.deinit();
}
}

View File

@ -7,8 +7,7 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef _NETWORK_DCE_H_
#define _NETWORK_DCE_H_
#pragma once
#ifdef __cplusplus
extern "C" {
@ -43,5 +42,3 @@ void modem_stop_network();
#ifdef __cplusplus
}
#endif
#endif //_NETWORK_DCE_H_

View File

@ -17,3 +17,7 @@ over PPPoS, i.e. over the modem serial line.
* Experiment with the network, after getting the IP from the modem device
- directly in the code
- in the system (need to set `tun` interface IP, dns servers, and routing the desired traffic over the tun interface)
### Supported IDF versions
This example (using the default CMake IDF build system) is only supported from `v4.4`, since is uses `idf.py`'s linux target.

View File

@ -5,5 +5,9 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${COMPONENT_LIB} PRIVATE Threads::Threads)
target_compile_features(${COMPONENT_LIB} PRIVATE cxx_std_17)
set_target_properties(${COMPONENT_LIB} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS ON
)
target_compile_definitions(${COMPONENT_LIB} PRIVATE "-DCONFIG_IDF_TARGET_LINUX")

View File

@ -7,39 +7,54 @@
#include "cxx_include/esp_modem_dte.hpp"
#include "esp_modem_config.h"
#include "esp_netif.h"
#include "vfs_resource/vfs_create.hpp"
#define CONFIG_EXAMPLE_SIM_PIN "1234"
#define CONFIG_USE_VFS_UART 1
using namespace esp_modem;
[[maybe_unused]] static const char *TAG = "linux_modem_main";
[[maybe_unused]] constexpr auto TAG = "linux_modem_main";
int main()
{
// init the DTE
esp_modem_dte_config_t dte_config = {
.dte_buffer_size = 512,
.task_stack_size = 1024,
.task_priority = 10,
.uart_config = { },
.vfs_config = { }
.dte_buffer_size = 512,
.task_stack_size = 1024,
.task_priority = 10,
.vfs_config = {}
};
dte_config.vfs_config.dev_name = "/dev/ttyUSB0";
dte_config.vfs_config.resource = ESP_MODEM_VFS_IS_UART; // This tells the VFS to init the UART (use termux to setup baudrate, etc.)
#if CONFIG_USE_VFS_UART == 1
struct esp_modem_vfs_uart_creator uart_config = {
.dev_name = "/dev/ttyUSB0",
.uart = {}
};
assert(vfs_create_uart(&uart_config, &dte_config.vfs_config) == true);
#else
/**
* @note: It is possible to setup a serial to socket bridge, running a this on a remote host which connects `/dev/ttyS0` to the modem
* socat TCP-L:2222 GOPEN:/dev/ttyS0,ispeed=115200,ospeed=1152000,b115200,raw,echo=0
*/
struct esp_modem_vfs_socket_creator socket_config = {
.host_name = "raspberrypi.local",
.port = 2222
};
assert(vfs_create_socket(&socket_config, &dte_config.vfs_config) == true);
#endif
auto dte = create_vfs_dte(&dte_config);
esp_netif_config_t netif_config = {
.dev_name = "/dev/net/tun",
.if_name = "tun0"
.dev_name = "/dev/net/tun",
.if_name = "tun0"
};
esp_netif_t *tun_netif = esp_netif_new(&netif_config);
auto uart_dte = create_vfs_dte(&dte_config);
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("internet");
auto dce = create_SIM7600_dce(&dce_config, uart_dte, tun_netif);
auto dce = create_SIM7600_dce(&dce_config, dte, tun_netif);
assert(dce != nullptr);
dce->set_command_mode();
@ -50,16 +65,18 @@ int main()
usleep(1000000);
}
std::string str;
dce->set_mode(esp_modem::modem_mode::CMUX_MODE);
// dce->set_mode(esp_modem::modem_mode::CMUX_MODE);
dce->get_imsi(str);
ESP_LOGI(TAG, "Modem IMSI number: %s",str.c_str());
ESP_LOGI(TAG, "Modem IMSI number: %s", str.c_str());
dce->get_imei(str);
ESP_LOGI(TAG, "Modem IMEI number: %s",str.c_str());
dce->get_operator_name(str);
ESP_LOGI(TAG, "Operator name: %s",str.c_str());
ESP_LOGI(TAG, "Modem IMEI number: %s", str.c_str());
while (command_result::OK != dce->get_operator_name(str)) {
printf(".\n");
}
ESP_LOGI(TAG, "Operator name: %s", str.c_str());
dce->set_mode(esp_modem::modem_mode::DATA_MODE);
usleep(100'000'000);
usleep(15'000'000);
esp_netif_destroy(tun_netif);
}

View File

@ -4,5 +4,13 @@ cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS "../..")
include($ENV{IDF_PATH}/tools/cmake/version.cmake)
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "4.4")
if(("${IDF_TARGET}" STREQUAL "esp32s2") OR ("${IDF_TARGET}" STREQUAL "esp32s3"))
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/peripherals/usb/host/cdc/common")
endif()
endif()
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(modem-console)

View File

@ -1,6 +1,4 @@
# PPPoS simple client example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
# Modem console example
## Overview
@ -14,4 +12,18 @@ This example implements two very simple network commands to demonstrate and test
To demonstrate creating custom modem devices, this example creates a DCE object using a locally defined create method,
that sets up the DCE based on a custom module implemented in the `my_module_dce.hpp` file. The module class only overrides
`get_module_name()` method supplying a user defined name, but keeps all other commands the same as defined in the `GenericModule`
class.
class.
### USB DTE support
For USB enabled targets (ESP32-S2 and ESP32-S3), it is possible to connect to the modem device via USB.
1. In menuconfig, navigate to `Example Configuration->Type of serial connection to the modem` and choose `USB`.
2. Connect the modem USB signals to pin 19 (DATA-) and 20 (DATA+) on your ESP chip.
USB example uses Quactel BG96 modem device.
### Supported IDF versions
This example is only supported from `v4.2`, due to support of the console repl mode.
USB example is supported from `v4.4`.

View File

@ -0,0 +1,19 @@
include($ENV{IDF_PATH}/tools/cmake/version.cmake)
idf_build_get_property(target IDF_TARGET)
# USB is supported on S2 and S3 targets and IDF version >= 4.4
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "4.4")
if(("${target}" STREQUAL "esp32s2") OR ("${target}" STREQUAL "esp32s3"))
idf_component_register(SRCS "esp_modem_usb.cpp" "esp_modem_usb_api_target.cpp"
REQUIRES cdc_acm_host esp_modem
REQUIRED_IDF_TARGETS esp32s2 esp32s3
PRIV_INCLUDE_DIRS "private_include"
INCLUDE_DIRS "include")
set_target_properties(${COMPONENT_LIB} PROPERTIES
CXX_STANDARD 17
)
endif()
endif()

View File

@ -0,0 +1,191 @@
// Copyright 2021 Espressif Systems (Shanghai) CO LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_modem_config.h"
#include "esp_modem_usb_config.h"
#include "cxx_include/esp_modem_dte.hpp"
#include "usb/usb_host.h"
#include "usb/cdc_acm_host.h"
#include "sdkconfig.h"
#include "usb_terminal.hpp"
static const char *TAG = "usb_terminal";
/**
* @brief USB Host task
*
* This task is created only if install_usb_host is set to true in DTE configuration.
* In case the user doesn't want in install USB Host driver here, he must install it before creating UsbTerminal object.
*
* @param arg Unused
*/
void usb_host_task(void *arg)
{
while (1) {
// Start handling system events
uint32_t event_flags;
usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
ESP_LOGD(TAG, "No more clients: clean up\n");
usb_host_device_free_all();
}
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
ESP_LOGD(TAG, "All free: uninstall USB lib\n");
break;
}
}
// Clean up USB Host
vTaskDelay(10); // Short delay to allow clients clean-up
usb_host_lib_handle_events(0, NULL); // Make sure there are now pending events
usb_host_uninstall();
vTaskDelete(NULL);
}
namespace esp_modem {
class UsbTerminal : public Terminal, private CdcAcmDevice {
public:
explicit UsbTerminal(const esp_modem_dte_config *config)
{
const struct esp_modem_usb_term_config* usb_config = (struct esp_modem_usb_term_config*)(config->extension_config);
// Install USB Host driver
if (usb_config->install_usb_host) {
const usb_host_config_t host_config = {
.skip_phy_setup = false,
.intr_flags = ESP_INTR_FLAG_LEVEL1,
};
throw_if_esp_fail(usb_host_install(&host_config), "USB Host install failed");
ESP_LOGD(TAG, "USB Host installed");
throw_if_false(pdTRUE == xTaskCreatePinnedToCore(usb_host_task, "usb_host", 4096, NULL, config->task_priority + 1, NULL, usb_config->xCoreID), "USB host task failed");
}
// Install CDC-ACM driver
const cdc_acm_host_driver_config_t esp_modem_cdc_acm_driver_config = {
.driver_task_stack_size = config->task_stack_size,
.driver_task_priority = config->task_priority,
.xCoreID = (BaseType_t)usb_config->xCoreID
};
// Silently continue of error: CDC-ACM driver might be already installed
cdc_acm_host_install(&esp_modem_cdc_acm_driver_config);
// Open CDC-ACM device
const cdc_acm_host_device_config_t esp_modem_cdc_acm_device_config = {
.connection_timeout_ms = usb_config->timeout_ms,
.out_buffer_size = config->dte_buffer_size,
.event_cb = handle_notif,
.data_cb = handle_rx,
.user_arg = this
};
if (usb_config->cdc_compliant) {
throw_if_esp_fail(this->CdcAcmDevice::open(usb_config->vid, usb_config->pid,
usb_config->interface_idx, &esp_modem_cdc_acm_device_config),
"USB Device open failed");
} else {
throw_if_esp_fail(this->CdcAcmDevice::open_vendor_specific(usb_config->vid, usb_config->pid,
usb_config->interface_idx, &esp_modem_cdc_acm_device_config),
"USB Device open failed");
}
};
~UsbTerminal()
{
this->CdcAcmDevice::close();
};
void start() override
{
return;
}
void stop() override
{
return;
}
int write(uint8_t *data, size_t len) override
{
ESP_LOG_BUFFER_HEXDUMP(TAG, data, len, ESP_LOG_DEBUG);
if (this->CdcAcmDevice::tx_blocking(data, len) != ESP_OK) {
return -1;
}
return len;
}
int read(uint8_t *data, size_t len) override
{
// This function should never be called. UsbTerminal provides data through Terminal::on_read callback
ESP_LOGW(TAG, "Unexpected call to UsbTerminal::read function");
return -1;
}
private:
UsbTerminal() = delete;
UsbTerminal(const UsbTerminal &copy) = delete;
UsbTerminal &operator=(const UsbTerminal &copy) = delete;
bool operator== (const UsbTerminal &param) const = delete;
bool operator!= (const UsbTerminal &param) const = delete;
static void handle_rx(uint8_t *data, size_t data_len, void *user_arg)
{
ESP_LOG_BUFFER_HEXDUMP(TAG, data, data_len, ESP_LOG_DEBUG);
UsbTerminal *this_terminal = static_cast<UsbTerminal *>(user_arg);
if (data_len > 0 && this_terminal->on_read) {
this_terminal->on_read(data, data_len);
} else {
ESP_LOGD(TAG, "Unhandled RX data");
}
}
static void handle_notif(cdc_acm_dev_hdl_t cdc_hdl, const cdc_acm_host_dev_event_data_t *event, void *user_ctx)
{
UsbTerminal *this_terminal = static_cast<UsbTerminal *>(user_ctx);
switch (event->type) {
// Notifications like Ring, Rx Carrier indication or Network connection indication are not relevant for USB terminal
case CDC_ACM_HOST_NETWORK_CONNECTION:
case CDC_ACM_HOST_SERIAL_STATE:
break;
case CDC_ACM_HOST_DEVICE_DISCONNECTED:
ESP_LOGW(TAG, "USB terminal disconnected");
cdc_acm_host_close(cdc_hdl);
if (this_terminal->on_error) {
this_terminal->on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
}
break;
case CDC_ACM_HOST_ERROR:
ESP_LOGE(TAG, "Unexpected CDC-ACM error: %d.", event->data.error);
if (this_terminal->on_error) {
this_terminal->on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
}
break;
default:
abort();
}
};
};
std::unique_ptr<Terminal> create_usb_terminal(const esp_modem_dte_config *config)
{
TRY_CATCH_RET_NULL(
return std::make_unique<UsbTerminal>(config);
)
}
} // namespace esp_modem

View File

@ -0,0 +1,32 @@
// Copyright 2021-2022 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "usb_terminal.hpp"
#include "cxx_include/esp_modem_api.hpp"
#include "cxx_include/esp_modem_netif.hpp"
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
static const char *TAG = "modem_usb_api_target";
#endif
namespace esp_modem {
std::shared_ptr<DTE> create_usb_dte(const dte_config *config)
{
TRY_CATCH_RET_NULL(
auto term = create_usb_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
)
}
}

View File

@ -0,0 +1,29 @@
// Copyright 2021-2022 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "cxx_include/esp_modem_dce.hpp"
#include "cxx_include/esp_modem_dce_module.hpp"
namespace esp_modem {
/**
* @brief Create USB DTE
*
* @param config DTE configuration
* @return shared ptr to DTE on success
* nullptr on failure (either due to insufficient memory or wrong dte configuration)
* if exceptions are disabled the API abort()'s on error
*/
std::shared_ptr<DTE> create_usb_dte(const dte_config *config);
}

View File

@ -0,0 +1,63 @@
// Copyright 2021-2022 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include <stdbool.h>
/**
* @brief USB configuration structure
* @see USB host CDC-ACM driver documentation for details about interfaces settings
*/
struct esp_modem_usb_term_config {
uint16_t vid; /*!< Vendor ID of the USB device */
uint16_t pid; /*!< Product ID of the USB device */
int interface_idx; /*!< USB Interface index that will be used */
uint32_t timeout_ms; /*!< Time for a USB modem to connect to USB host. 0 means wait forever. */
int xCoreID; /*!< Core affinity of created tasks: CDC-ACM driver task and optional USB Host task */
bool cdc_compliant; /*!< Treat the USB device as CDC-compliant. Read CDC-ACM driver documentation for more details */
bool install_usb_host; /*!< Flag whether USB Host driver should be installed */
};
/**
* @brief ESP Mode USB DTE Default Configuration
*
* @param[in] _usb_config esp_modem_usb_term_config configuration structure. Can be obtained by ESP_MODEM_DEFAULT_USB_CONFIG
*
*/
#define ESP_MODEM_DTE_DEFAULT_USB_CONFIG(_usb_config) \
{ \
.dte_buffer_size = 512, \
.task_stack_size = 4096, \
.task_priority = 5, \
.extension_config = &_usb_config \
}
/**
* @brief ESP Modem USB Default Configuration
*
* @param[in] _vid USB Vendor ID
* @param[in] _pid USB Product ID
* @see USB host CDC-ACM driver documentation for details about interfaces settings
*/
#define ESP_MODEM_DEFAULT_USB_CONFIG(_vid, _pid) \
{ \
.vid = _vid, \
.pid = _pid, \
.interface_idx = 0, \
.timeout_ms = 0, \
.xCoreID = 0, \
.cdc_compliant = false, \
.install_usb_host = true \
}

View File

@ -0,0 +1,51 @@
// Copyright 2021 Espressif Systems (Shanghai) CO LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "cxx_include/esp_modem_dte.hpp"
#include "sdkconfig.h"
#include "esp_log.h"
struct esp_modem_dte_config;
// Copy-pasted from esp_modem/private_include/exception_stub.hpp
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
#define TRY_CATCH_OR_DO(block, action) \
try { block \
} catch (std::bad_alloc& e) { \
ESP_LOGE(TAG, "Out of memory"); \
action; \
} catch (::esp_modem::esp_err_exception& e) { \
esp_err_t err = e.get_err_t(); \
ESP_LOGE(TAG, "%s: Exception caught with ESP err_code=%d", __func__, err); \
ESP_LOGE(TAG, "%s", e.what()); \
action; \
}
#define TRY_CATCH_RET_NULL(block) TRY_CATCH_OR_DO(block, return nullptr)
#else
#define TRY_CATCH_OR_DO(block, action) \
block
#define TRY_CATCH_RET_NULL(block) \
block
#endif
namespace esp_modem {
std::unique_ptr<Terminal> create_usb_terminal(const esp_modem_dte_config *config);
} // namespace esp_modem

View File

@ -2,4 +2,5 @@ idf_component_register(SRCS "modem_console_main.cpp"
"console_helper.cpp"
"httpget_handle.c"
"ping_handle.c"
REQUIRES console esp_http_client nvs_flash esp_modem esp_modem_usb_dte
INCLUDE_DIRS ".")

View File

@ -0,0 +1,17 @@
menu "Example Configuration"
choice EXAMPLE_SERIAL_CONFIG
prompt "Type of serial connection to the modem"
default EXAMPLE_SERIAL_CONFIG_UART
config EXAMPLE_SERIAL_CONFIG_UART
bool "UART"
help
Connect to modem via UART.
config EXAMPLE_SERIAL_CONFIG_USB
bool "USB"
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
Connect to modem via USB (CDC-ACM class). For IDF version >= 4.4.
endchoice
endmenu

View File

@ -12,50 +12,52 @@
static const char *TAG = "modem_console_helper";
ConsoleCommand::ConsoleCommand(const char* command, const char* help, const std::vector<CommandArgs>& args, std::function<bool(ConsoleCommand *)> f):
func(std::move(f))
ConsoleCommand::ConsoleCommand(const char *command, const char *help, const std::vector<CommandArgs> &args, std::function<bool(ConsoleCommand *)> f):
func(std::move(f))
{
RegisterCommand(command, help, args);
}
void ConsoleCommand::RegisterCommand(const char* command, const char* help, const std::vector<CommandArgs>& args)
void ConsoleCommand::RegisterCommand(const char *command, const char *help, const std::vector<CommandArgs> &args)
{
assert(last_command <= MAX_REPEAT_NR);
void * common_arg = nullptr;
for (auto it: args) {
switch(it.type) {
case ARG_END:
break;
case STR0:
common_arg = arg_str0(it.shortopts, it.longopts, it.datatype, it.glossary);
break;
case STR1:
common_arg = arg_str1(it.shortopts, it.longopts, it.datatype, it.glossary);
break;
case INT0:
common_arg = arg_int0(it.shortopts, it.longopts, it.datatype, it.glossary);
break;
case INT1:
common_arg = arg_int1(it.shortopts, it.longopts, it.datatype, it.glossary);
break;
case LIT0:
common_arg = arg_lit0(it.shortopts, it.longopts, it.glossary);
break;
arg_type common_arg = { };
for (auto &it : args) {
switch (it.type) {
case ARG_END:
break;
case STR0:
common_arg.str = arg_str0(it.shortopts, it.longopts, it.datatype, it.glossary);
break;
case STR1:
common_arg.str = arg_str1(it.shortopts, it.longopts, it.datatype, it.glossary);
break;
case INT0:
common_arg.intx = arg_int0(it.shortopts, it.longopts, it.datatype, it.glossary);
break;
case INT1:
common_arg.intx = arg_int1(it.shortopts, it.longopts, it.datatype, it.glossary);
break;
case LIT0:
common_arg.lit = arg_lit0(it.shortopts, it.longopts, it.glossary);
break;
}
if (common_arg) {
if (common_arg.is_null()) {
arg_table.emplace_back(common_arg);
} else {
ESP_LOGE(TAG, "Creating argument parser failed for %s", it.glossary);
abort();
}
}
arg_table.emplace_back( arg_end(1));
arg_type end = { .end = arg_end(1) };
arg_table.emplace_back(end);
const esp_console_cmd_t command_def = {
.command = command,
.help = help,
.hint = nullptr,
.func = command_func_pts[last_command],
.argtable = &arg_table[0]
.command = command,
.help = help,
.hint = nullptr,
.func = command_func_pts[last_command],
.argtable = &arg_table[0]
};
ESP_ERROR_CHECK(esp_console_cmd_register(&command_def));
last_command++;
@ -64,13 +66,13 @@ void ConsoleCommand::RegisterCommand(const char* command, const char* help, cons
int ConsoleCommand::get_count(int index)
{
return ((struct arg_str *)arg_table[index])->count;
return (arg_table[index].str)->count;
}
std::string ConsoleCommand::get_string(int index)
{
if (get_count(index) > 0) {
return std::string(((struct arg_str *)arg_table[index])->sval[0]);
return std::string(arg_table[index].str->sval[0]);
}
return std::string();
}
@ -78,17 +80,18 @@ std::string ConsoleCommand::get_string(int index)
int ConsoleCommand::get_int(int index)
{
if (get_count(index) > 0) {
return *((struct arg_int *)arg_table[index])->ival;
return *(arg_table[index].intx)->ival;
}
return -1;
}
int ConsoleCommand::command_func(int argc, char **argv) {
void * plain_arg_array = &arg_table[0];
int ConsoleCommand::command_func(int argc, char **argv)
{
arg_type *plain_arg_array = &arg_table[0];
int nerrors = arg_parse(argc, argv, (void **)plain_arg_array);
if (nerrors != 0) {
arg_print_errors(stderr, (struct arg_end *) arg_table.back(), argv[0]);
arg_print_errors(stderr, arg_table.back().end, argv[0]);
return 1;
}
if (func) {
@ -120,7 +123,7 @@ const esp_console_cmd_func_t ConsoleCommand::command_func_pts[] = {
#define ITEM_TO_REPEAT(index) StaticCommands::command_func_ ## index ,
_DO_REPEAT_ITEM()
_DO_REPEAT_ITEM()
#undef ITEM_TO_REPEAT
};
@ -128,5 +131,5 @@ const esp_console_cmd_func_t ConsoleCommand::command_func_pts[] = {
/**
* @brief Static members defined for ConsoleCommand
*/
std::vector<ConsoleCommand*> ConsoleCommand::console_commands;
std::vector<ConsoleCommand *> ConsoleCommand::console_commands;
int ConsoleCommand::last_command = 0;

View File

@ -7,8 +7,7 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef MODEM_CONSOLE_CONSOLE_HELPER_H
#define MODEM_CONSOLE_CONSOLE_HELPER_H
#pragma once
#include <vector>
#include <algorithm>
@ -35,10 +34,10 @@ enum arg_type {
* Command argument struct definition for list of arguments of one command
*/
struct CommandArgs {
CommandArgs(arg_type t, const char * shopts, const char * lopts, const char * data, const char * glos):
CommandArgs(arg_type t, const char *shopts, const char *lopts, const char *data, const char *glos):
type(t), shortopts(shopts), longopts(lopts), datatype(data), glossary(glos) {}
CommandArgs(arg_type t, const char * shopts, const char * lopts, const char * glos):
type(t), shortopts(shopts), longopts(lopts), datatype(nullptr), glossary(glos) {}
CommandArgs(arg_type t, const char *shopts, const char *lopts, const char *glos):
type(t), shortopts(shopts), longopts(lopts), datatype(nullptr), glossary(glos) {}
arg_type type;
const char *shortopts;
@ -53,6 +52,21 @@ class StaticCommands;
* @brief This class simplifies console command definition in more object wise fashion
*/
class ConsoleCommand {
/**
* @brief Common argument types to be stored internally for parsing later
*/
using arg_type =
union {
struct arg_int *intx;
struct arg_str *str;
struct arg_lit *lit;
struct arg_end *end;
void *__raw_ptr;
bool is_null() const {
return __raw_ptr;
}
};
friend class StaticCommands;
public:
/**
@ -63,8 +77,8 @@ public:
* @param srg_struct_size Size of the argument struct
* @param f Function callback for the command
*/
template<typename T> explicit ConsoleCommand(const char* command, const char* help, const T *arg_struct, size_t srg_struct_size,
std::function<bool(ConsoleCommand *)> f): func(std::move(f))
template<typename T> explicit ConsoleCommand(const char *command, const char *help, const T *arg_struct, size_t srg_struct_size,
std::function<bool(ConsoleCommand *)> f): func(std::move(f))
{
size_t args_plain_size = srg_struct_size / sizeof(CommandArgs);
auto first_arg = reinterpret_cast<const CommandArgs *>(arg_struct);
@ -75,29 +89,38 @@ public:
/**
* @brief Another method of Console command definitions using vector arg struct
*/
explicit ConsoleCommand(const char* command, const char* help, const std::vector<CommandArgs>& args, std::function<bool(ConsoleCommand *)> f);
explicit ConsoleCommand(const char *command, const char *help, const std::vector<CommandArgs> &args, std::function<bool(ConsoleCommand *)> f);
/**
* @brief Utility getters of various params from the argument list
*/
template<typename T> int get_count_of(CommandArgs T::*member) { return get_count(index_arg(member)); }
template<typename T> std::string get_string_of(CommandArgs T::*member) { return get_string(index_arg(member)); }
template<typename T> int get_int_of(CommandArgs T::*member) { return get_int(index_arg(member)); }
template<typename T> int get_count_of(CommandArgs T::*member)
{
return get_count(index_arg(member));
}
template<typename T> std::string get_string_of(CommandArgs T::*member)
{
return get_string(index_arg(member));
}
template<typename T> int get_int_of(CommandArgs T::*member)
{
return get_int(index_arg(member));
}
std::string get_string(int index);
int get_int(int index);
private:
int get_count(int index);
void RegisterCommand(const char* command, const char* help, const std::vector<CommandArgs>& args);
void RegisterCommand(const char *command, const char *help, const std::vector<CommandArgs> &args);
template<typename T> static constexpr size_t index_arg(CommandArgs T::*member)
{ return ((uint8_t *)&((T*)nullptr->*member) - (uint8_t *)nullptr)/sizeof(CommandArgs); }
std::vector<void*> arg_table;
{
return ((uint8_t *) & ((T *)nullptr->*member) - (uint8_t *)nullptr) / sizeof(CommandArgs);
}
std::vector<arg_type> arg_table;
int command_func(int argc, char **argv);
static int last_command;
static std::vector<ConsoleCommand*> console_commands;
static std::vector<ConsoleCommand *> console_commands;
std::function<bool(ConsoleCommand *)> func;
const static esp_console_cmd_func_t command_func_pts[];
};
#endif //MODEM_CONSOLE_CONSOLE_HELPER_H

View File

@ -46,6 +46,7 @@ static esp_err_t http_event_handler(esp_http_client_event_t *evt)
case HTTP_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
break;
default: break;
}
return ESP_OK;
}
@ -83,9 +84,9 @@ static int do_http_client(int argc, char **argv)
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
uint64_t content_length = esp_http_client_get_content_length(client);
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %lld",
esp_http_client_get_status_code(client), content_length);
return 0;
}
ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
@ -105,4 +106,4 @@ void modem_console_register_http(void)
.argtable = &http_args
};
ESP_ERROR_CHECK(esp_console_cmd_register(&http_cmd));
}
}

View File

@ -18,6 +18,10 @@
#include "cxx_include/esp_modem_dte.hpp"
#include "esp_modem_config.h"
#include "cxx_include/esp_modem_api.hpp"
#if defined(CONFIG_USB_OTG_SUPPORTED)
#include "esp_modem_usb_config.h"
#include "cxx_include/esp_modem_usb_api.hpp"
#endif
#include "esp_log.h"
#include "console_helper.hpp"
#include "my_module_dce.hpp"
@ -53,13 +57,29 @@ extern "C" void app_main(void)
ESP_ERROR_CHECK(esp_event_loop_create_default());
// init the netif, DTE and DCE respectively
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(DEFAULT_APN);
esp_netif_config_t ppp_netif_config = ESP_NETIF_DEFAULT_PPP();
esp_netif_t *esp_netif = esp_netif_new(&ppp_netif_config);
assert(esp_netif);
#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_UART)
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
auto uart_dte = create_uart_dte(&dte_config);
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(DEFAULT_APN);
auto dce = create_shiny_dce(&dce_config, uart_dte, esp_netif);
#elif defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
struct esp_modem_usb_term_config usb_config = ESP_MODEM_DEFAULT_USB_CONFIG(0x2C7C, 0x0296); // VID and PID of BG96 modem
// BG96 modem implements Vendor Specific class, that is CDC-ACM like. Interface for AT commands has index no. 2.
usb_config.interface_idx = 2;
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_USB_CONFIG(usb_config);
ESP_LOGI(TAG, "Waiting for USB device connection...");
auto dte = create_usb_dte(&dte_config);
std::unique_ptr<DCE> dce = create_BG96_dce(&dce_config, dte, esp_netif);
#else
#error Invalid serial connection to modem.
#endif
assert(dce != nullptr);
// init console REPL environment
@ -73,7 +93,7 @@ extern "C" void app_main(void)
SetModeArgs(): mode(STR1, nullptr, nullptr, "<mode>", "PPP, CMD or CMUX") {}
CommandArgs mode;
} set_mode_args;
const ConsoleCommand SetModeParser("set_mode", "sets modem mode", &set_mode_args, sizeof(set_mode_args), [&](ConsoleCommand *c){
const ConsoleCommand SetModeParser("set_mode", "sets modem mode", &set_mode_args, sizeof(set_mode_args), [&](ConsoleCommand * c) {
if (c->get_count_of(&SetModeArgs::mode)) {
auto mode = c->get_string_of(&SetModeArgs::mode);
modem_mode dev_mode;
@ -101,7 +121,7 @@ extern "C" void app_main(void)
SetPinArgs(): pin(STR1, nullptr, nullptr, "<pin>", "PIN") {}
CommandArgs pin;
} set_pin_args;
const ConsoleCommand SetPinParser("set_pin", "sets SIM card PIN", &set_pin_args, sizeof(set_pin_args), [&](ConsoleCommand *c){
const ConsoleCommand SetPinParser("set_pin", "sets SIM card PIN", &set_pin_args, sizeof(set_pin_args), [&](ConsoleCommand * c) {
if (c->get_count_of(&SetPinArgs::pin)) {
auto pin = c->get_string_of(&SetPinArgs::pin);
ESP_LOGI(TAG, "Setting pin=%s...", pin.c_str());
@ -109,7 +129,7 @@ extern "C" void app_main(void)
if (err == command_result::OK) {
ESP_LOGI(TAG, "OK");
} else {
ESP_LOGE(TAG, "Failed %s", err == command_result::TIMEOUT ? "TIMEOUT":"");
ESP_LOGE(TAG, "Failed %s", err == command_result::TIMEOUT ? "TIMEOUT" : "");
return 1;
}
}
@ -117,26 +137,26 @@ extern "C" void app_main(void)
});
const std::vector<CommandArgs> no_args;
const ConsoleCommand ReadPinArgs("read_pin", "checks if SIM is unlocked", no_args, [&](ConsoleCommand *c){
const ConsoleCommand ReadPinArgs("read_pin", "checks if SIM is unlocked", no_args, [&](ConsoleCommand * c) {
bool pin_ok;
ESP_LOGI(TAG, "Checking pin...");
auto err = dce->read_pin(pin_ok);
if (err == command_result::OK) {
ESP_LOGI(TAG, "OK. Pin status: %s", pin_ok ? "true": "false");
ESP_LOGI(TAG, "OK. Pin status: %s", pin_ok ? "true" : "false");
} else {
ESP_LOGE(TAG, "Failed %s", err == command_result::TIMEOUT ? "TIMEOUT":"");
ESP_LOGE(TAG, "Failed %s", err == command_result::TIMEOUT ? "TIMEOUT" : "");
return 1;
}
return 0;
});
const ConsoleCommand GetModuleName("get_module_name", "reads the module name", no_args, [&](ConsoleCommand *c){
const ConsoleCommand GetModuleName("get_module_name", "reads the module name", no_args, [&](ConsoleCommand * c) {
std::string module_name;
ESP_LOGI(TAG, "Reading module name...");
CHECK_ERR(dce->get_module_name(module_name), ESP_LOGI(TAG, "OK. Module name: %s", module_name.c_str()));
});
const ConsoleCommand GetOperatorName("get_operator_name", "reads the operator name", no_args, [&](ConsoleCommand *c){
const ConsoleCommand GetOperatorName("get_operator_name", "reads the operator name", no_args, [&](ConsoleCommand * c) {
std::string operator_name;
ESP_LOGI(TAG, "Reading operator name...");
CHECK_ERR(dce->get_operator_name(operator_name), ESP_LOGI(TAG, "OK. Operator name: %s", operator_name.c_str()));
@ -153,39 +173,41 @@ extern "C" void app_main(void)
CommandArgs pattern;
CommandArgs no_cr;
} send_cmd_args;
const ConsoleCommand SendCommand("cmd", "sends generic AT command, no_args", &send_cmd_args, sizeof(send_cmd_args), [&](ConsoleCommand *c) {
const ConsoleCommand SendCommand("cmd", "sends generic AT command, no_args", &send_cmd_args, sizeof(send_cmd_args), [&](ConsoleCommand * c) {
auto cmd = c->get_string_of(&GenericCommandArgs::cmd);
auto timeout = c->get_count_of(&GenericCommandArgs::timeout) ? c->get_int_of(&GenericCommandArgs::timeout)
: 1000;
: 1000;
ESP_LOGI(TAG, "Sending command %s with timeout %d", cmd.c_str(), timeout);
auto pattern = c->get_string_of(&GenericCommandArgs::pattern);
if (c->get_count_of(&GenericCommandArgs::no_cr) == 0) {
cmd += '\r';
}
ESP_LOGI(TAG, "Sending command %s with timeout %d", cmd.c_str(), timeout);
CHECK_ERR(dce->command(cmd, [&](uint8_t *data, size_t len) {
std::string response((char *) data, len);
ESP_LOGI(TAG, "%s", response.c_str());
if (pattern.empty() || response.find(pattern) != std::string::npos)
if (pattern.empty() || response.find(pattern) != std::string::npos) {
return command_result::OK;
if (response.find(pattern) != std::string::npos)
}
if (response.find(pattern) != std::string::npos) {
return command_result::OK;
}
return command_result::TIMEOUT;
}, timeout),);
});
const ConsoleCommand GetSignalQuality("get_signal_quality", "Gets signal quality", no_args, [&](ConsoleCommand *c){
const ConsoleCommand GetSignalQuality("get_signal_quality", "Gets signal quality", no_args, [&](ConsoleCommand * c) {
int rssi, ber;
CHECK_ERR(dce->get_signal_quality(rssi, ber), ESP_LOGI(TAG, "OK. rssi=%d, ber=%d", rssi, ber));
});
const ConsoleCommand GetBatteryStatus("get_battery_status", "Reads voltage/battery status", no_args, [&](ConsoleCommand *c){
const ConsoleCommand GetBatteryStatus("get_battery_status", "Reads voltage/battery status", no_args, [&](ConsoleCommand * c) {
int volt, bcl, bcs;
CHECK_ERR(dce->get_battery_status(volt, bcl, bcs), ESP_LOGI(TAG, "OK. volt=%d, bcl=%d, bcs=%d", volt, bcl, bcs));
});
const ConsoleCommand PowerDown("power_down", "power down the module", no_args, [&](ConsoleCommand *c){
const ConsoleCommand PowerDown("power_down", "power down the module", no_args, [&](ConsoleCommand * c) {
ESP_LOGI(TAG, "Power down the module...");
CHECK_ERR(dce->power_down(), ESP_LOGI(TAG, "OK"));
});
const ConsoleCommand Reset("reset", "reset the module", no_args, [&](ConsoleCommand *c){
const ConsoleCommand Reset("reset", "reset the module", no_args, [&](ConsoleCommand * c) {
ESP_LOGI(TAG, "Resetting the module...");
CHECK_ERR(dce->reset(), ESP_LOGI(TAG, "OK"));
});
@ -193,7 +215,7 @@ extern "C" void app_main(void)
SetApn(): apn(STR1, nullptr, nullptr, "<apn>", "APN (Access Point Name)") {}
CommandArgs apn;
} set_apn;
const ConsoleCommand SetApnParser("set_apn", "sets APN", &set_apn, sizeof(set_apn), [&](ConsoleCommand *c){
const ConsoleCommand SetApnParser("set_apn", "sets APN", &set_apn, sizeof(set_apn), [&](ConsoleCommand * c) {
if (c->get_count_of(&SetApn::apn)) {
auto apn = c->get_string_of(&SetApn::apn);
ESP_LOGI(TAG, "Setting the APN=%s...", apn.c_str());
@ -205,7 +227,7 @@ extern "C" void app_main(void)
});
SignalGroup exit_signal;
const ConsoleCommand ExitConsole("exit", "exit the console application", no_args, [&](ConsoleCommand *c){
const ConsoleCommand ExitConsole("exit", "exit the console application", no_args, [&](ConsoleCommand * c) {
ESP_LOGI(TAG, "Exiting...");
exit_signal.set(1);
s_repl->del(s_repl);

View File

@ -7,8 +7,7 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef __MY_MODULE_DCE_HPP__
#define __MY_MODULE_DCE_HPP__
#pragma once
#include "cxx_include/esp_modem_dce_factory.hpp"
@ -21,7 +20,7 @@
class MyShinyModem: public esp_modem::GenericModule {
using GenericModule::GenericModule;
public:
esp_modem::command_result get_module_name(std::string& name) override
esp_modem::command_result get_module_name(std::string &name) override
{
name = "Custom Shiny Module";
return esp_modem::command_result::OK;
@ -33,11 +32,8 @@ public:
* @return unique pointer of the resultant DCE
*/
std::unique_ptr<esp_modem::DCE> create_shiny_dce(const esp_modem::dce_config *config,
std::shared_ptr<esp_modem::DTE> dte,
esp_netif_t *netif)
std::shared_ptr<esp_modem::DTE> dte,
esp_netif_t *netif)
{
return esp_modem::dce_factory::Factory::build_unique<MyShinyModem>(config, std::move(dte), netif);
}
#endif //__MY_MODULE_DCE_HPP__

View File

@ -8,3 +8,7 @@ This example shows how to act as a MQTT client after the PPPoS channel created b
## How to use this example
See the README.md file in the upper level `pppos` directory for more information about the PPPoS examples.
### Supported IDF versions
This example is only supported from `v4.1`, as this is the default dependency of `esp-modem` component.

View File

@ -143,7 +143,21 @@ void app_main(void)
// Init netif object
esp_netif_t *esp_netif = esp_netif_new(&netif_ppp_config);
assert(esp_netif);
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
ESP_LOGI(TAG, "Initializing esp_modem for the BG96 module...");
esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_BG96, &dte_config, &dce_config, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 == 1
ESP_LOGI(TAG, "Initializing esp_modem for the SIM800 module...");
esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_SIM800, &dte_config, &dce_config, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
ESP_LOGI(TAG, "Initializing esp_modem for the SIM7600 module...");
esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_SIM7600, &dte_config, &dce_config, esp_netif);
#else
ESP_LOGI(TAG, "Initializing esp_modem for a generic module...");
esp_modem_dce_t *dce = esp_modem_new(&dte_config, &dce_config, esp_netif);
#endif
assert(dce);
#if CONFIG_EXAMPLE_NEED_SIM_PIN == 1
// check if PIN needed

View File

@ -15,3 +15,7 @@ The example uses the following configuration options to demonstrate basic esp-mo
## About the esp_modem
Please check the component [README](../../README.md)
### Supported IDF versions
This example is only supported from `v4.3`, since is uses an experimental `esp_event_cxx` component.

View File

@ -1,2 +1,2 @@
idf_component_register(SRCS "simple_client.cpp" "simple_mqtt_client.cpp"
idf_component_register(SRCS "simple_cmux_client_main.cpp" "simple_mqtt_client.cpp"
INCLUDE_DIRS ".")

View File

@ -19,7 +19,7 @@
#include "simple_mqtt_client.hpp"
#include "esp_vfs_dev.h" // For optional VFS support
#include "esp_https_ota.h" // For potential OTA configuration
#include "vfs_resource/vfs_create.hpp"
#define BROKER_URL "mqtt://mqtt.eclipseprojects.io"
@ -46,11 +46,11 @@ extern "C" void app_main(void)
* so doesn't give any practical benefit besides the FD use demonstration and a placeholder
* to use FD terminal for other devices
*/
dte_config.vfs_config.dev_name = "/dev/uart/1";
dte_config.vfs_config.resource = ESP_MODEM_VFS_IS_UART;
dte_config.uart_config.event_queue_size = 0;
struct esp_modem_vfs_uart_creator uart_config = ESP_MODEM_VFS_DEFAULT_UART_CONFIG("/dev/uart/1");
assert(vfs_create_uart(&uart_config, &dte_config.vfs_config) == true);
auto dte = create_vfs_dte(&dte_config);
esp_vfs_dev_uart_use_driver(dte_config.uart_config.port_num);
esp_vfs_dev_uart_use_driver(uart_config.uart.port_num);
#else
auto dte = create_uart_dte(&dte_config);
#endif // CONFIG_EXAMPLE_USE_VFS_TERM
@ -70,9 +70,9 @@ extern "C" void app_main(void)
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
std::unique_ptr<DCE> dce = create_BG96_dce(&dce_config, dte, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 == 1
std::unique_ptr<DCE> dce = create_SIM800_dce(&dce_config, uart_dte, esp_netif);
std::unique_ptr<DCE> dce = create_SIM800_dce(&dce_config, dte, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
std::unique_ptr<DCE> dce = create_SIM7600_dce(&dce_config, uart_dte, esp_netif);
std::unique_ptr<DCE> dce = create_SIM7600_dce(&dce_config, dte, esp_netif);
#else
#error "Unsupported device"
#endif
@ -122,10 +122,10 @@ extern "C" void app_main(void)
event_handler.listen_to(MqttClient::get_event(MqttClient::Event::DATA));
auto reg = loop->register_event(MqttClient::get_event(MqttClient::Event::DATA),
[&mqtt](const ESPEvent &event, void *data) {
std::cout << " TOPIC:" << mqtt.get_topic(data) << std::endl;
std::cout << " DATA:" << mqtt.get_data(data) << std::endl;
});
[&mqtt](const ESPEvent & event, void *data) {
std::cout << " TOPIC:" << mqtt.get_topic(data) << std::endl;
std::cout << " DATA:" << mqtt.get_data(data) << std::endl;
});
mqtt.connect();
while (true) {
result = event_handler.wait_event_for(std::chrono::milliseconds(60000));

View File

@ -22,9 +22,8 @@ ESP_EVENT_DECLARE_BASE(MQTT_EVENTS);
/**
* Thin wrapper around C mqtt_client
*/
struct MqttClientHandle
{
explicit MqttClientHandle(const std::string & uri)
struct MqttClientHandle {
explicit MqttClientHandle(const std::string &uri)
{
esp_mqtt_client_config_t config = { };
config.uri = uri.c_str();
@ -49,9 +48,9 @@ struct MqttClientHandle
/**
* @brief Definitions of MqttClient methods
*/
MqttClient::MqttClient(const std::string & uri):
MqttClient::MqttClient(const std::string &uri):
h(std::unique_ptr<MqttClientHandle>(new MqttClientHandle(uri)))
{}
{}
void MqttClient::connect()
{
@ -61,11 +60,11 @@ void MqttClient::connect()
idf::event::ESPEvent MqttClient::get_event(MqttClient::Event ev)
{
switch (ev) {
case Event::CONNECT: {
return { MQTT_EVENTS, ESPEventID(MQTT_EVENT_CONNECTED) };
}
case Event::DATA:
return { MQTT_EVENTS, ESPEventID(MQTT_EVENT_DATA) };
case Event::CONNECT: {
return { MQTT_EVENTS, ESPEventID(MQTT_EVENT_CONNECTED) };
}
case Event::DATA:
return { MQTT_EVENTS, ESPEventID(MQTT_EVENT_DATA) };
}
return { };
}
@ -80,7 +79,7 @@ int MqttClient::subscribe(const std::string &topic, int qos)
return esp_mqtt_client_subscribe(h->client, topic.c_str(), qos);
}
std::string MqttClient::get_topic(void * event_data)
std::string MqttClient::get_topic(void *event_data)
{
auto event = (esp_mqtt_event_handle_t)event_data;
if (event == nullptr || event->client != h->client)
@ -89,7 +88,7 @@ std::string MqttClient::get_topic(void * event_data)
return std::string(event->topic, event->topic_len);
}
std::string MqttClient::get_data(void * event_data)
std::string MqttClient::get_data(void *event_data)
{
auto event = (esp_mqtt_event_handle_t)event_data;
if (event == nullptr || event->client != h->client)

View File

@ -6,8 +6,7 @@
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef _SIMPLE_MQTT_CLIENT_H_
#define _SIMPLE_MQTT_CLIENT_H_
#pragma once
#include <string>
#include <memory>
@ -25,7 +24,7 @@ public:
DATA,
};
explicit MqttClient(const std::string & uri);
explicit MqttClient(const std::string &uri);
~MqttClient();
/**
@ -40,7 +39,7 @@ public:
* @param qos QoS (0 by default)
* @return message id
*/
int publish(const std::string & topic, const std::string & data, int qos = 0);
int publish(const std::string &topic, const std::string &data, int qos = 0);
/**
* @brief Subscribe to a topic
@ -48,7 +47,7 @@ public:
* @param qos QoS (0 by default)
* @return message id
*/
int subscribe(const std::string & topic, int qos = 0);
int subscribe(const std::string &topic, int qos = 0);
/**
* @brief Get topic from event data
@ -72,6 +71,3 @@ public:
private:
std::unique_ptr<MqttClientHandle> h;
};
#endif //_SIMPLE_MQTT_CLIENT_H_

View File

@ -6,5 +6,7 @@ CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
CONFIG_LWIP_PPP_ENABLE_IPV6=n
CONFIG_COMPILER_CXX_EXCEPTIONS=y
CONFIG_PARTITION_TABLE_TWO_OTA=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF=y
CONFIG_NEWLIB_STDIN_LINE_ENDING_LF=y
CONFIG_NEWLIB_STDIN_LINE_ENDING_LF=y
CONFIG_MAIN_TASK_STACK_SIZE=8192

View File

@ -1,5 +1,6 @@
version: "0.1.5"
version: "0.1.16"
description: esp modem
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_modem
dependencies:
# Required IDF version
idf:

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_API_HPP_
#define _ESP_MODEM_API_HPP_
#pragma once
#include <memory>
#include "cxx_include/esp_modem_dce.hpp"
@ -74,7 +73,7 @@ std::shared_ptr<DTE> create_vfs_dte(const dte_config *config);
/**
* @brief Create DCE based on SIM7600 module
* @param config DCE configuration
* @param DTE reference to the communicating DTE
* @param dte reference to the communicating DTE
* @param netif reference to the network interface
*
* @return unique ptr to the created DCE on success
@ -83,6 +82,17 @@ std::shared_ptr<DTE> create_vfs_dte(const dte_config *config);
*/
std::unique_ptr<DCE> create_SIM7600_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif);
/**
* @brief Create DCE based on SIM7070 module
*/
std::unique_ptr<DCE> create_SIM7070_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif);
/**
* @brief Create DCE based on SIM7000 module
*/
std::unique_ptr<DCE> create_SIM7000_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif);
/**
* @brief Create DCE based on SIM800 module
*/
@ -103,5 +113,3 @@ std::unique_ptr<DCE> create_generic_dce(const dce_config *config, std::shared_pt
*/
} // namespace esp_modem
#endif // _ESP_MODEM_API_HPP_

View File

@ -12,14 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_CMUX_HPP_
#define _ESP_MODEM_CMUX_HPP_
#pragma once
#include "esp_modem_terminal.hpp"
namespace esp_modem {
constexpr size_t max_terms = 2;
constexpr size_t MAX_TERMINALS_NUM = 2;
/**
* @defgroup ESP_MODEM_CMUX ESP_MODEM CMUX class
* @brief Definition of CMUX terminal
@ -51,38 +50,79 @@ class CMuxInstance;
/**
* @brief CMux class which consumes the original terminal and creates multiple virtual terminals from it.
* This class is not usable applicable as a DTE terminal
* This class itself is not usable as a DTE terminal, only via its instances defined in `CMuxInstance`
*/
class CMux {
public:
explicit CMux(std::unique_ptr<Terminal> t, std::unique_ptr<uint8_t[]> b, size_t buff_size):
term(std::move(t)), buffer_size(buff_size), buffer(std::move(b)), payload_start(nullptr), total_payload_size(0) {}
term(std::move(t)), payload_start(nullptr), total_payload_size(0), buffer_size(buff_size), buffer(std::move(b)) {}
~CMux() = default;
/**
* @brief Initializes CMux protocol
* @return true on success
*/
[[nodiscard]] bool init();
/**
* @brief Sets read callback for the appropriate terminal
* @param inst Index of the terminal
* @param f function pointer
*/
void set_read_cb(int inst, std::function<bool(uint8_t *data, size_t len)> f);
/**
* @brief Writes to the appropriate terminal
* @param i Index of the terminal
* @param data Data to write
* @param len Data length to write
* @return The actual written length
*/
int write(int i, uint8_t *data, size_t len);
private:
std::function<bool(uint8_t *data, size_t len)> read_cb[max_terms];
void data_available(uint8_t *data, size_t len);
void send_sabm(size_t i);
std::unique_ptr<Terminal> term;
cmux_state state;
static uint8_t fcs_crc(const uint8_t frame[6]); /*!< Utility to calculate FCS CRC */
void data_available(uint8_t *data, size_t len); /*!< Called when valid data available */
void send_sabm(size_t i); /*!< Sending initial SABM */
bool on_cmux(uint8_t *data, size_t len); /*!< Called from terminal layer when raw CMUX protocol data available */
struct CMuxFrame; /*!< Forward declare the Frame struct, used in protocol decoders */
/**
* These methods serve different states of the CMUX protocols
* @param frame Currently available cmux frame (basically data, size, methods)
* @return - true if the state processed successfully
* - false if more data needed to process the current state
*/
bool on_recovery(CMuxFrame &frame);
bool on_init(CMuxFrame &frame);
bool on_header(CMuxFrame &frame);
bool on_payload(CMuxFrame &frame);
bool on_footer(CMuxFrame &frame);
std::function<bool(uint8_t *data, size_t len)> read_cb[MAX_TERMINALS_NUM]; /*!< Function pointers to read callbacks */
std::unique_ptr<Terminal> term; /*!< The original terminal */
cmux_state state; /*!< CMux protocol state */
/**
* CMux control fields and offsets
*/
uint8_t dlci;
uint8_t type;
size_t payload_len;
uint8_t frame_header[6];
size_t frame_header_offset;
size_t buffer_size;
std::unique_ptr<uint8_t[]> buffer;
bool on_cmux(uint8_t *data, size_t len);
static uint8_t fcs_crc(const uint8_t frame[6]);
Lock lock;
int instance;
int sabm_ack;
uint8_t *payload_start;
size_t total_payload_size;
int instance;
int sabm_ack;
/**
* Processing buffer size and pointer
*/
size_t buffer_size;
std::unique_ptr<uint8_t[]> buffer;
Lock lock;
};
/**
@ -93,14 +133,23 @@ class CMuxInstance: public Terminal {
public:
explicit CMuxInstance(std::shared_ptr<CMux> parent, int i): cmux(std::move(parent)), instance(i) {}
int write(uint8_t *data, size_t len) override { return cmux->write(instance, data, len); }
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override { return cmux->set_read_cb(instance, std::move(f)); }
int read(uint8_t *data, size_t len) override { return 0; }
int write(uint8_t *data, size_t len) override
{
return cmux->write(instance, data, len);
}
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override
{
return cmux->set_read_cb(instance, std::move(f));
}
int read(uint8_t *data, size_t len) override
{
return 0;
}
void start() override { }
void stop() override { }
private:
std::shared_ptr<CMux> cmux;
int instance;
size_t instance;
};
/**
@ -108,5 +157,3 @@ private:
*/
} // namespace esp_modem
#endif // _ESP_MODEM_CMUX_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_COMMAND_LIBRARY_HPP_
#define _ESP_MODEM_COMMAND_LIBRARY_HPP_
#pragma once
#include "esp_modem_dte.hpp"
#include "esp_modem_dce_module.hpp"
@ -37,17 +36,20 @@ namespace dce_commands {
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \
return_type name(CommandableIf *t, ## __VA_ARGS__);
DECLARE_ALL_COMMAND_APIS(declare name(Commandable *p, ...);)
DECLARE_ALL_COMMAND_APIS(declare name(Commandable *p, ...);)
#undef ESP_MODEM_DECLARE_DCE_COMMAND
/**
* @brief Following commands that are different for some specific modules
*/
command_result get_battery_status_sim7xxx(CommandableIf* t, int& voltage, int &bcs, int &bcl);
command_result power_down_sim7xxx(CommandableIf* t);
command_result power_down_sim8xx(CommandableIf* t);
command_result set_data_mode_sim8xx(CommandableIf* t);
command_result get_battery_status_sim7xxx(CommandableIf *t, int &voltage, int &bcs, int &bcl);
command_result set_gnss_power_mode_sim76xx(CommandableIf *t, int mode);
command_result power_down_sim76xx(CommandableIf *t);
command_result power_down_sim70xx(CommandableIf *t);
command_result set_network_bands_sim76xx(CommandableIf *t, const std::string& mode, const int* bands, int size);
command_result power_down_sim8xx(CommandableIf *t);
command_result set_data_mode_sim8xx(CommandableIf *t);
/**
* @}
@ -55,5 +57,3 @@ command_result set_data_mode_sim8xx(CommandableIf* t);
} // dce_commands
} // esp_modem
#endif //_ESP_MODEM_COMMAND_LIBRARY_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_DCE_HPP_
#define _ESP_MODEM_DCE_HPP_
#pragma once
#include <utility>
#include "cxx_include/esp_modem_netif.hpp"
@ -35,7 +34,7 @@ namespace esp_modem {
*/
class DCE_Mode {
public:
DCE_Mode(): mode(modem_mode::COMMAND_MODE) {}
DCE_Mode(): mode(modem_mode::UNDEF) {}
~DCE_Mode() = default;
bool set(DTE *dte, ModuleIf *module, Netif &netif, modem_mode m);
modem_mode get();
@ -53,8 +52,8 @@ template<class SpecificModule>
class DCE_T {
static_assert(std::is_base_of<ModuleIf, SpecificModule>::value, "DCE must be instantiated with Module class only");
public:
explicit DCE_T(const std::shared_ptr<DTE>& dte, std::shared_ptr<SpecificModule> dev, esp_netif_t * netif):
dte(dte), device(std::move(dev)), netif(dte, netif)
explicit DCE_T(const std::shared_ptr<DTE> &dte, std::shared_ptr<SpecificModule> dev, esp_netif_t *netif):
dte(dte), device(std::move(dev)), netif(dte, netif)
{ }
~DCE_T() = default;
@ -62,20 +61,35 @@ public:
/**
* @brief Set data mode!
*/
void set_data() { set_mode(modem_mode::DATA_MODE); }
void set_data()
{
set_mode(modem_mode::DATA_MODE);
}
void exit_data() { set_mode(modem_mode::COMMAND_MODE); }
void exit_data()
{
set_mode(modem_mode::COMMAND_MODE);
}
void set_cmux() { set_mode(modem_mode::CMUX_MODE); }
void set_cmux()
{
set_mode(modem_mode::CMUX_MODE);
}
SpecificModule* get_module() { return device.get(); }
SpecificModule *get_module()
{
return device.get();
}
command_result command(const std::string& command, got_line_cb got_line, uint32_t time_ms)
command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms)
{
return dte->command(command, std::move(got_line), time_ms);
}
bool set_mode(modem_mode m) { return mode.set(dte.get(), device.get(), netif, m); }
bool set_mode(modem_mode m)
{
return mode.set(dte.get(), device.get(), netif, m);
}
protected:
std::shared_ptr<DTE> dte;
@ -86,9 +100,9 @@ protected:
/**
* @brief Common abstraction of the modem DCE, specialized by the GenericModule which is a parent class for the supported
* defices and most common modems, as well.
* devices and most common modems, as well.
*/
class DCE: public DCE_T<GenericModule> {
class DCE : public DCE_T<GenericModule> {
public:
using DCE_T<GenericModule>::DCE_T;
@ -99,7 +113,10 @@ public:
return device->name(std::forward<Agrs>(args)...); \
}
DECLARE_ALL_COMMAND_APIS(forwards name(...) { device->name(...); } )
DECLARE_ALL_COMMAND_APIS(forwards name(...)
{
device->name(...);
} )
#undef ESP_MODEM_DECLARE_DCE_COMMAND
@ -110,5 +127,3 @@ public:
*/
} // esp_modem
#endif // _ESP_MODEM_DCE_HPP_

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_DCE_FACTORY_HPP_
#define _ESP_MODEM_DCE_FACTORY_HPP_
#pragma once
#include "esp_log.h"
/**
* @defgroup ESP_MODEM_DCE_FACTORY
@ -31,85 +31,94 @@ using config = ::esp_modem_dce_config;
/**
* @brief Helper class for creating a uder define pointer in a specific way, either as a plain pointer, shared_ptr or unique_ptr
* @brief Helper class for creating a user define pointer in a specific way, either as a plain pointer, shared_ptr or unique_ptr
*/
class FactoryHelper {
public:
static std::unique_ptr<PdpContext> create_pdp_context(std::string &apn);
template <typename T, typename Ptr, typename ...Args>
static auto make(Args&&... args) -> typename std::enable_if<std::is_same<Ptr, T*>::value, T*>::type
template <typename T, typename T_Ptr, typename ...Args>
static auto make(Args &&... args) -> typename std::enable_if<std::is_same<T_Ptr, T *>::value, T *>::type
{
return new T(std::forward<Args>(args)...);
}
template <typename T, typename Ptr, typename ...Args>
static auto make(Args&&... args) -> typename std::enable_if<std::is_same<Ptr, std::shared_ptr<T>>::value, std::shared_ptr<T>>::type
template <typename T, typename T_Ptr, typename ...Args>
static auto make(Args &&... args) -> typename std::enable_if<std::is_same<T_Ptr, std::shared_ptr<T>>::value, std::shared_ptr<T>>::type
{
return std::make_shared<T>(std::forward<Args>(args)...);
}
template <typename T, typename Ptr = std::unique_ptr<T>, typename ...Args>
static auto make(Args&&... args) -> typename std::enable_if<std::is_same<Ptr, std::unique_ptr<T>>::value, std::unique_ptr<T>>::type
template <typename T, typename T_Ptr = std::unique_ptr<T>, typename ...Args>
static auto make(Args && ... args) -> typename std::enable_if<std::is_same<T_Ptr, std::unique_ptr<T>>::value, std::unique_ptr<T>>::type
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
};
/**
* @brief Builder class for building a DCE_T<Module> in a specific way, either form a Module object or by default from the DTE and netif
* @brief Creator class for building a DCE_T<Module> in a specific way, either from a Module object or by default from the DTE and netif
*
* @throws
* - esp_modem::esp_err_exception on invalid arguments
* - std::bad_alloc if failed to allocate
*/
template<typename Module>
class Builder {
static_assert(std::is_base_of<ModuleIf, Module>::value, "Builder must be used only for Module classes");
template<typename T_Module>
class Creator {
static_assert(std::is_base_of<ModuleIf, T_Module>::value, "Builder must be used only for Module classes");
public:
Builder(std::shared_ptr<DTE> x, esp_netif_t* esp_netif): dte(std::move(x)), device(nullptr), netif(esp_netif)
Creator(std::shared_ptr<DTE> dte, esp_netif_t *esp_netif): dte(std::move(dte)), device(nullptr), netif(esp_netif)
{
throw_if_false(netif != nullptr, "Null netif");
}
Builder(std::shared_ptr<DTE> dte, esp_netif_t* esp_netif, std::shared_ptr<Module> dev): dte(std::move(dte)), device(std::move(dev)), netif(esp_netif)
Creator(std::shared_ptr<DTE> dte, esp_netif_t *esp_netif, std::shared_ptr<T_Module> dev): dte(std::move(dte)), device(std::move(dev)), netif(esp_netif)
{
throw_if_false(netif != nullptr, "Null netif");
}
~Builder()
~Creator()
{
throw_if_false(device == nullptr, "module was captured or created but never used");
if (device != nullptr) {
ESP_LOGE("dce_factory::~Creator", "module was captured or created but never used");
}
}
template<typename Ptr>
auto create_module(const esp_modem_dce_config *config) -> Ptr
template<typename T_Ptr>
auto create_module(const esp_modem_dce_config *config) -> T_Ptr
{
return FactoryHelper::make<Module, Ptr>(dte, config);
return FactoryHelper::make<T_Module, T_Ptr>(dte, config);
}
template<typename DceT, typename Ptr>
auto create(const esp_modem_dce_config *config) -> Ptr
template<typename T_Dce, typename T_Ptr>
auto create(const esp_modem_dce_config *config) -> T_Ptr
{
if (dte == nullptr)
if (dte == nullptr) {
return nullptr;
}
if (device == nullptr) {
device = create_module<decltype(device)>(config);
if (device == nullptr)
if (device == nullptr) {
return nullptr;
}
}
return FactoryHelper::make<DceT, Ptr>(std::move(dte), std::move(device), netif);
return FactoryHelper::make<T_Dce, T_Ptr>(std::move(dte), std::move(device), netif);
}
private:
std::shared_ptr<DTE> dte;
std::shared_ptr<Module> device;
std::shared_ptr<T_Module> device;
esp_netif_t *netif;
};
/**
* @brief Specific modem choice when creating by the Factory
*/
enum class Modem {
enum class ModemType {
GenericModule, /*!< Default generic module with the most common commands */
SIM7600, /*!< Derived from the GenericModule, specifics applied to SIM7600 model */
SIM7070, /*!< Derived from the GenericModule, specifics applied to SIM7070 model */
SIM7000, /*!< Derived from the GenericModule, specifics applied to SIM7000 model */
BG96, /*!< Derived from the GenericModule, specifics applied to BG69 model */
SIM800, /*!< Derived from the GenericModule with specifics applied to SIM800 model */
};
@ -120,7 +129,7 @@ enum class Modem {
*/
class Factory {
public:
explicit Factory(Modem modem): m(modem) {}
explicit Factory(ModemType modem): m(modem) {}
/**
* @brief Create a default unique_ptr DCE in a specific way (from the module)
@ -130,10 +139,10 @@ public:
* @param args typically a DTE object and a netif handle for PPP network
* @return unique_ptr DCE of the created DCE on success
*/
template <typename Module, typename ...Args>
static std::unique_ptr<DCE> build_unique(const config *cfg, Args&&... args)
template <typename T_Module, typename ...Args>
static std::unique_ptr<DCE> build_unique(const config *cfg, Args &&... args)
{
return build_generic_DCE<Module, DCE, std::unique_ptr<DCE>>(cfg, std::forward<Args>(args)...);
return build_generic_DCE<T_Module, DCE, std::unique_ptr<DCE>>(cfg, std::forward<Args>(args)...);
}
/**
@ -144,34 +153,38 @@ public:
* @param args typically a DTE object and a netif handle for PPP network
* @return DCE pointer the created DCE on success
*/
template <typename Module, typename ...Args>
static DCE* build(const config *cfg, Args&&... args)
template <typename T_Module, typename ...Args>
static DCE *build(const config *cfg, Args &&... args)
{
return build_generic_DCE<Module, DCE>(cfg, std::forward<Args>(args)...);
return build_generic_DCE<T_Module, DCE>(cfg, std::forward<Args>(args)...);
}
template <typename Module, typename ...Args>
static std::shared_ptr<Module> build_shared_module(const config *cfg, Args&&... args)
template <typename T_Module, typename ...Args>
static std::shared_ptr<T_Module> build_shared_module(const config *cfg, Args &&... args)
{
return build_module_T<Module>(cfg, std::forward<Args>(args)...);
return build_module_T<T_Module>(cfg, std::forward<Args>(args)...);
}
template <typename ...Args>
std::shared_ptr<GenericModule> build_shared_module(const config *cfg, Args&&... args)
std::shared_ptr<GenericModule> build_shared_module(const config *cfg, Args &&... args)
{
switch (m) {
case Modem::SIM800:
return build_shared_module<SIM800>(cfg, std::forward<Args>(args)...);
case Modem::SIM7600:
return build_shared_module<SIM7600>(cfg, std::forward<Args>(args)...);
case Modem::BG96:
return build_shared_module<BG96>(cfg, std::forward<Args>(args)...);
case Modem::GenericModule:
return build_shared_module<GenericModule>(cfg, std::forward<Args>(args)...);
default:
break;
case ModemType::SIM800:
return build_shared_module<SIM800>(cfg, std::forward<Args>(args)...);
case ModemType::SIM7600:
return build_shared_module<SIM7600>(cfg, std::forward<Args>(args)...);
case ModemType::SIM7070:
return build_shared_module<SIM7070>(cfg, std::forward<Args>(args)...);
case ModemType::SIM7000:
return build_shared_module<SIM7000>(cfg, std::forward<Args>(args)...);
case ModemType::BG96:
return build_shared_module<BG96>(cfg, std::forward<Args>(args)...);
case ModemType::GenericModule:
return build_shared_module<GenericModule>(cfg, std::forward<Args>(args)...);
default:
break;
}
return nullptr;
}
@ -184,58 +197,66 @@ public:
* @return unique_ptr DCE of the created DCE on success
*/
template <typename ...Args>
std::unique_ptr<DCE> build_unique(const config *cfg, Args&&... args)
std::unique_ptr<DCE> build_unique(const config *cfg, Args &&... args)
{
switch (m) {
case Modem::SIM800:
return build_unique<SIM800>(cfg, std::forward<Args>(args)...);
case Modem::SIM7600:
return build_unique<SIM7600>(cfg, std::forward<Args>(args)...);
case Modem::BG96:
return build_unique<BG96>(cfg, std::forward<Args>(args)...);
case Modem::GenericModule:
return build_unique<GenericModule>(cfg, std::forward<Args>(args)...);
default:
break;
case ModemType::SIM800:
return build_unique<SIM800>(cfg, std::forward<Args>(args)...);
case ModemType::SIM7600:
return build_unique<SIM7600>(cfg, std::forward<Args>(args)...);
case ModemType::SIM7070:
return build_unique<SIM7070>(cfg, std::forward<Args>(args)...);
case ModemType::SIM7000:
return build_unique<SIM7000>(cfg, std::forward<Args>(args)...);
case ModemType::BG96:
return build_unique<BG96>(cfg, std::forward<Args>(args)...);
case ModemType::GenericModule:
return build_unique<GenericModule>(cfg, std::forward<Args>(args)...);
default:
break;
}
return nullptr;
}
template <typename ...Args>
DCE* build(const config *cfg, Args&&... args)
DCE *build(const config *cfg, Args &&... args)
{
switch (m) {
case Modem::SIM800:
return build<SIM800>(cfg, std::forward<Args>(args)...);
case Modem::SIM7600:
return build<SIM7600>(cfg, std::forward<Args>(args)...);
case Modem::BG96:
return build<BG96>(cfg, std::forward<Args>(args)...);
case Modem::GenericModule:
return build<GenericModule>(cfg, std::forward<Args>(args)...);
default:
break;
case ModemType::SIM800:
return build<SIM800>(cfg, std::forward<Args>(args)...);
case ModemType::SIM7600:
return build<SIM7600>(cfg, std::forward<Args>(args)...);
case ModemType::SIM7070:
return build<SIM7070>(cfg, std::forward<Args>(args)...);
case ModemType::SIM7000:
return build<SIM7000>(cfg, std::forward<Args>(args)...);
case ModemType::BG96:
return build<BG96>(cfg, std::forward<Args>(args)...);
case ModemType::GenericModule:
return build<GenericModule>(cfg, std::forward<Args>(args)...);
default:
break;
}
return nullptr;
}
private:
Modem m;
ModemType m;
protected:
template <typename Module, typename Ptr = std::shared_ptr<Module>, typename ...Args>
static Ptr build_module_T(const config *cfg, Args&&... args)
template <typename T_Module, typename Ptr = std::shared_ptr<T_Module>, typename ...Args>
static Ptr build_module_T(const config *cfg, Args && ... args)
{
Builder<Module> b(std::forward<Args>(args)...);
return b.template create_module<Ptr>(cfg);
Creator<T_Module> creator(std::forward<Args>(args)...);
return creator.template create_module<Ptr>(cfg);
}
template <typename Module, typename Dce = DCE_T<Module>, typename DcePtr = Dce*, typename ...Args>
static DcePtr build_generic_DCE(const config *cfg, Args&&... args)
template <typename T_Module, typename T_Dce = DCE_T<T_Module>, typename T_DcePtr = T_Dce *, typename ...Args>
static auto build_generic_DCE(const config *cfg, Args && ... args) -> T_DcePtr
{
Builder<Module> b(std::forward<Args>(args)...);
return b.template create<Dce, DcePtr>(cfg);
Creator<T_Module> creator(std::forward<Args>(args)...);
return creator.template create<T_Dce, T_DcePtr>(cfg);
}
};
@ -244,6 +265,3 @@ protected:
*/
} // namespace esp_modem::dce_factory
#endif // _ESP_MODEM_DCE_FACTORY_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_DCE_MODULE_
#define _ESP_MODEM_DCE_MODULE_
#pragma once
#include <memory>
#include <utility>
@ -48,8 +47,8 @@ public:
* The configuration could be either the dce-config struct or just a pdp context
*/
explicit GenericModule(std::shared_ptr<DTE> dte, std::unique_ptr<PdpContext> pdp):
dte(std::move(dte)), pdp(std::move(pdp)) {}
explicit GenericModule(std::shared_ptr<DTE> dte, const esp_modem_dce_config* config);
dte(std::move(dte)), pdp(std::move(pdp)) {}
explicit GenericModule(std::shared_ptr<DTE> dte, const esp_modem_dce_config *config);
/**
* @brief This is a mandatory method for ModuleIf class, which sets up the device
@ -59,10 +58,12 @@ public:
*/
bool setup_data_mode() override
{
if (set_echo(false) != command_result::OK)
if (set_echo(false) != command_result::OK) {
return false;
if (set_pdp_context(*pdp) != command_result::OK)
}
if (set_pdp_context(*pdp) != command_result::OK) {
return false;
}
return true;
}
@ -73,10 +74,12 @@ public:
bool set_mode(modem_mode mode) override
{
if (mode == modem_mode::DATA_MODE) {
if (set_data_mode() != command_result::OK)
if (set_data_mode() != command_result::OK) {
return resume_data_mode() == command_result::OK;
}
return true;
} else if (mode == modem_mode::COMMAND_MODE) {
Task::Delay(1000); // Mandatory 1s pause
return set_command_mode() == command_result::OK;
} else if (mode == modem_mode::CMUX_MODE) {
return set_cmux() == command_result::OK;
@ -116,8 +119,27 @@ protected:
class SIM7600: public GenericModule {
using GenericModule::GenericModule;
public:
command_result get_module_name(std::string& name) override;
command_result get_battery_status(int& voltage, int &bcs, int &bcl) override;
command_result get_battery_status(int &voltage, int &bcs, int &bcl) override;
command_result power_down() override;
command_result set_gnss_power_mode(int mode) override;
command_result set_network_bands(const std::string& mode, const int* bands, int size) override;
};
/**
* @brief Specific definition of the SIM7070 module
*/
class SIM7070: public GenericModule {
using GenericModule::GenericModule;
public:
command_result power_down() override;
};
/**
* @brief Specific definition of the SIM7000 module
*/
class SIM7000: public GenericModule {
using GenericModule::GenericModule;
public:
command_result power_down() override;
};
@ -127,7 +149,6 @@ public:
class SIM800: public GenericModule {
using GenericModule::GenericModule;
public:
command_result get_module_name(std::string& name) override;
command_result power_down() override;
command_result set_data_mode() override;
};
@ -137,8 +158,6 @@ public:
*/
class BG96: public GenericModule {
using GenericModule::GenericModule;
public:
command_result get_module_name(std::string& name) override;
};
/**
@ -146,5 +165,3 @@ public:
*/
} // namespace esp_modem
#endif // _ESP_MODEM_DCE_MODULE_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_DTE_HPP_
#define _ESP_MODEM_DTE_HPP_
#pragma once
#include <memory>
#include <cstddef>
@ -117,5 +116,3 @@ private:
*/
} // namespace esp_modem
#endif // _ESP_MODEM_DTE_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_EXCEPTION_HPP_
#define _ESP_MODEM_EXCEPTION_HPP_
#pragma once
#include <string>
#include "esp_err.h"
@ -27,9 +26,13 @@ public:
explicit esp_err_exception(esp_err_t err): esp_err(err) {}
explicit esp_err_exception(std::string msg): esp_err(ESP_FAIL), message(std::move(msg)) {}
explicit esp_err_exception(std::string msg, esp_err_t err): esp_err(err), message(std::move(msg)) {}
virtual esp_err_t get_err_t() { return esp_err; }
virtual esp_err_t get_err_t()
{
return esp_err;
}
~esp_err_exception() noexcept override = default;
virtual const char* what() const noexcept {
virtual const char *what() const noexcept
{
return message.c_str();
}
private:
@ -62,5 +65,3 @@ static inline void throw_if_esp_fail(esp_err_t err)
}
} // namespace esp_modem
#endif //_ESP_MODEM_EXCEPTION_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_NETIF_HPP
#define _ESP_MODEM_NETIF_HPP
#pragma once
#include <memory>
#include <cstddef>
@ -74,7 +73,7 @@ private:
std::shared_ptr<DTE> ppp_dte;
esp_netif_t *netif;
struct ppp_netif_driver driver{};
struct ppp_netif_driver driver {};
SignalGroup signal;
static const size_t PPP_STARTED = SignalGroup::bit0;
static const size_t PPP_EXIT = SignalGroup::bit1;
@ -85,5 +84,3 @@ private:
*/
} // namespace esp_modem
#endif // _ESP_MODEM_NETIF_HPP

View File

@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_PRIMITIVES_HPP_
#define _ESP_MODEM_PRIMITIVES_HPP_
#pragma once
#include "esp_event.h"
#include "esp_modem_exception.hpp"
#if defined(CONFIG_IDF_TARGET_LINUX)
@ -21,9 +22,9 @@
#include <thread>
#else
#include "freertos/event_groups.h"
// forward declarations of FreeRTOS primitives
struct QueueDefinition;
typedef void * EventGroupHandle_t;
#endif
@ -31,10 +32,10 @@ namespace esp_modem {
// Forward declaration for both linux/FreeRTOS targets
//
using TaskFunction_t = void (*)(void*);
using TaskFunction_t = void (*)(void *);
#if !defined(CONFIG_IDF_TARGET_LINUX)
struct Lock {
using MutexT = QueueDefinition*;
using MutexT = QueueHandle_t;
explicit Lock();
~Lock();
void lock();
@ -42,8 +43,8 @@ struct Lock {
private:
MutexT m{};
};
using TaskT = void*;
using SignalT = void*;
using TaskT = TaskHandle_t;
using SignalT = EventGroupHandle_t;
#else
using Lock = std::mutex;
struct SignalGroupInternal;
@ -55,11 +56,17 @@ static constexpr uint32_t portMAX_DELAY = UINT32_MAX;
template<class T>
class Scoped {
public:
explicit Scoped(T &l):lock(l) { lock.lock(); }
~Scoped() { lock.unlock(); }
explicit Scoped(T &l): lock(l)
{
lock.lock();
}
~Scoped()
{
lock.unlock();
}
private:
T& lock;
T &lock;
};
class Task {
@ -69,6 +76,7 @@ public:
static void Delete();
static void Relinquish();
static void Delay(uint32_t delay);
private:
TaskT task_handle;
};
@ -102,5 +110,3 @@ private:
};
} // namespace esp_modem
#endif // _ESP_MODEM_PRIMITIVES_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_TERMINAL_HPP_
#define _ESP_MODEM_TERMINAL_HPP_
#pragma once
#include <memory>
#include <functional>
@ -45,15 +44,21 @@ enum class terminal_error {
};
/**
* @brief Terminal interface. All communication interfaces must comply this interface in order to be used as a DTE
* @brief Terminal interface. All communication interfaces must comply to this interface in order to be used as a DTE
*/
class Terminal {
public:
virtual ~Terminal() = default;
void set_error_cb(std::function<void(terminal_error)> f) { on_error = std::move(f); }
void set_error_cb(std::function<void(terminal_error)> f)
{
on_error = std::move(f);
}
virtual void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) { on_data = std::move(f); }
virtual void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f)
{
on_read = std::move(f);
}
/**
* @brief Writes data to the terminal
@ -76,7 +81,7 @@ public:
virtual void stop() = 0;
protected:
std::function<bool(uint8_t *data, size_t len)> on_data;
std::function<bool(uint8_t *data, size_t len)> on_read;
std::function<void(terminal_error)> on_error;
};
@ -85,5 +90,3 @@ protected:
*/
} // namespace esp_modem
#endif // _ESP_MODEM_TERMINAL_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_TYPES_HPP_
#define _ESP_MODEM_TYPES_HPP_
#pragma once
#include <functional>
#include <string>
@ -68,6 +67,12 @@ struct PdpContext {
*/
class CommandableIf {
public:
CommandableIf() = default;
CommandableIf(const CommandableIf&) = delete;
CommandableIf& operator=(const CommandableIf&) = delete;
CommandableIf(CommandableIf&&) = delete;
CommandableIf& operator=(CommandableIf&&) = delete;
virtual ~CommandableIf() = default;
/**
* @brief Sends custom AT command
* @param command Command to be sent
@ -84,8 +89,14 @@ public:
*/
class ModuleIf {
public:
ModuleIf() = default;
ModuleIf(const ModuleIf&) = delete;
ModuleIf& operator=(const ModuleIf&) = delete;
ModuleIf(ModuleIf&&) = delete;
ModuleIf& operator=(ModuleIf&&) = delete;
virtual ~ModuleIf() = default;
/**
* @brief Sets the data mode up (provides the necessary configuration to connect to the cellular network
* @brief Sets the data mode up (provides the necessary configuration to connect to the cellular network)
* @return true on success
*/
virtual bool setup_data_mode() = 0;
@ -103,5 +114,3 @@ public:
*/
} // namespace esp_modem
#endif // _ESP_MODEM_TYPES_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_API_H_
#define _ESP_MODEM_API_H_
#pragma once
#include "esp_err.h"
#include "generate/esp_modem_command_declare.inc"
@ -35,6 +34,3 @@ DECLARE_ALL_COMMAND_APIS(declares esp_modem_<API>(esp_modem_t * dce, ...);)
#ifdef __cplusplus
}
#endif
#endif // _CLIENT_ESP_MODEM_API_H_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_C_API_TYPES_H_
#define _ESP_MODEM_C_API_TYPES_H_
#pragma once
#include "esp_modem_config.h"
@ -49,6 +48,8 @@ typedef enum esp_modem_dce_device
{
ESP_MODEM_DCE_GENETIC, /**< The most generic device */
ESP_MODEM_DCE_SIM7600,
ESP_MODEM_DCE_SIM7070,
ESP_MODEM_DCE_SIM7000,
ESP_MODEM_DCE_BG96,
ESP_MODEM_DCE_SIM800,
} esp_modem_dce_device_t;
@ -98,5 +99,3 @@ esp_err_t esp_modem_set_mode(esp_modem_dce_t * dce, esp_modem_dce_mode_t mode);
#ifdef __cplusplus
}
#endif
#endif //_ESP_MODEM_C_API_TYPES_H_

View File

@ -12,11 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_CONFIG_H_
#define _ESP_MODEM_CONFIG_H_
#pragma once
#include "driver/uart.h"
#include "esp_modem_dce_config.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup ESP_MODEM_CONFIG
* @brief Configuration structures for DTE and DCE
@ -56,23 +60,17 @@ struct esp_modem_uart_term_config {
int event_queue_size; /*!< UART Event Queue Size, set to 0 if no event queue needed */
};
/**
* @brief Resources used by VFS terminal
*
*/
typedef enum {
ESP_MODEM_VFS_IS_EXTERN = 0, /*!< External resource: internal VFS terminal takes no action to setup this */
ESP_MODEM_VFS_IS_UART, /*!< VFS uses UART: internal VFS initializes UART based on esp_modem_uart_term_config */
} esp_modem_vfs_resource_t;
// Forward declare the resource struct
struct esp_modem_vfs_resource;
/**
* @brief VFS configuration structure
*
*/
struct esp_modem_vfs_term_config {
const char* dev_name; /*!< VFS device name, e.g. /dev/uart/n */
esp_modem_vfs_resource_t resource; /*!< Underlying device which gets initialized during VFS init */
int fd; /*!< Already created file descriptor */
void (*deleter)(int, struct esp_modem_vfs_resource*); /*!< Custom close function for the fd */
struct esp_modem_vfs_resource *resource; /*!< Resource attached to the VFS (need for clenaup) */
};
/**
@ -85,9 +83,12 @@ struct esp_modem_vfs_term_config {
struct esp_modem_dte_config {
size_t dte_buffer_size; /*!< DTE buffer size */
uint32_t task_stack_size; /*!< Terminal task stack size */
int task_priority; /*!< Terminal task priority */
struct esp_modem_uart_term_config uart_config; /*!< Configuration for UART Terminal */
struct esp_modem_vfs_term_config vfs_config; /*!< Configuration for VFS Terminal */
unsigned task_priority; /*!< Terminal task priority */
union {
struct esp_modem_uart_term_config uart_config; /*!< Configuration for UART Terminal */
struct esp_modem_vfs_term_config vfs_config; /*!< Configuration for VFS Terminal */
void *extension_config; /*!< Configuration for app specific Terminal */
};
};
@ -115,10 +116,6 @@ struct esp_modem_dte_config {
.tx_buffer_size = 512, \
.event_queue_size = 30, \
}, \
.vfs_config = { \
.dev_name = "/null", \
.resource = ESP_MODEM_VFS_IS_EXTERN \
}\
}
typedef struct esp_modem_dte_config esp_modem_dte_config_t;
@ -127,4 +124,6 @@ typedef struct esp_modem_dte_config esp_modem_dte_config_t;
* @}
*/
#endif // _ESP_MODEM_CONFIG_H_
#ifdef __cplusplus
}
#endif

View File

@ -12,8 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_MODEM_DCE_CONFIG_H_
#define _ESP_MODEM_DCE_CONFIG_H_
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup ESP_MODEM_CONFIG
* @{
@ -41,5 +44,6 @@ struct esp_modem_dce_config {
* @}
*/
#endif // _ESP_MODEM_DCE_CONFIG_H_
#ifdef __cplusplus
}
#endif

View File

@ -28,15 +28,17 @@
#define BOOL_IN(param, name) const bool _ARG(param, name)
#define BOOL_OUT(param, name) bool& _ARG(param, name)
#define INT_OUT(param, name) int& _ARG(param, name)
#define INTEGER_LIST_IN(param, name) const int* _ARG(param, name)
#define STRUCT_OUT(struct_name, x) struct_name& x
#define STRUCT_OUT(struct_name, p1) struct_name& p1
#else
#define STRING_IN(param, name) const char* _ARG(param, name)
#define STRING_OUT(param, name) char* _ARG(param, name)
#define BOOL_IN(param, name) const bool _ARG(param, name)
#define BOOL_OUT(param, name) bool* _ARG(param, name)
#define INT_OUT(param, name) int* _ARG(param, name)
#define STRUCT_OUT(struct_name, x) struct struct_name* x
#define INTEGER_LIST_IN(param, name) const int* _ARG(param, name)
#define STRUCT_OUT(struct_name, p1) struct struct_name* p1
#endif
#define DECLARE_ALL_COMMAND_APIS(...) \
@ -47,10 +49,10 @@
ESP_MODEM_DECLARE_DCE_COMMAND(sync, command_result, 0) \
/**
* @brief Reads the operator name
* @param[out] name module name
* @param[out] operator name
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_operator_name, command_result, 1, STRING_OUT(x, name)) \
ESP_MODEM_DECLARE_DCE_COMMAND(get_operator_name, command_result, 1, STRING_OUT(p1, name)) \
\
/**
* @brief Stores current user profile
@ -63,28 +65,28 @@ ESP_MODEM_DECLARE_DCE_COMMAND(store_profile, command_result, 0) \
* @param[in] pin Pin
* @return OK, FAIL or TIMEOUT
*/\
ESP_MODEM_DECLARE_DCE_COMMAND(set_pin, command_result, 1, STRING_IN(x, pin)) \
ESP_MODEM_DECLARE_DCE_COMMAND(set_pin, command_result, 1, STRING_IN(p1, pin)) \
\
/**
* @brief Checks if the SIM needs a PIN
* @param[out] pin_ok true if the SIM card doesn't need a PIN to unlock
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(read_pin, command_result, 1, BOOL_OUT(x, pin_ok)) \
ESP_MODEM_DECLARE_DCE_COMMAND(read_pin, command_result, 1, BOOL_OUT(p1, pin_ok)) \
\
/**
* @brief Sets echo mode
* @param[in] echo_on true if echo mode on (repeats the commands)
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_echo, command_result, 1, BOOL_IN(x, echo_on)) \
ESP_MODEM_DECLARE_DCE_COMMAND(set_echo, command_result, 1, BOOL_IN(p1, echo_on)) \
\
/**
* @brief Sets the Txt or Pdu mode for SMS (only txt is supported)
* @param[in] txt true if txt mode
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(sms_txt_mode, command_result, 1, BOOL_IN(x, txt)) \
ESP_MODEM_DECLARE_DCE_COMMAND(sms_txt_mode, command_result, 1, BOOL_IN(p1, txt)) \
\
/**
* @brief Sets the default (GSM) charater set
@ -98,7 +100,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(sms_character_set, command_result, 0) \
* @param[in] message Text message to be sent
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(send_sms, command_result, 2, STRING_IN(x, number), STRING_IN(y, message)) \
ESP_MODEM_DECLARE_DCE_COMMAND(send_sms, command_result, 2, STRING_IN(p1, number), STRING_IN(p2, message)) \
\
/**
* @brief Resumes data mode (Switches back to th data mode, which was temporarily suspended)
@ -108,10 +110,10 @@ ESP_MODEM_DECLARE_DCE_COMMAND(resume_data_mode, command_result, 0) \
\
/**
* @brief Sets php context
* @param[in] x PdP context struct to setup modem cellular connection
* @param[in] p1 PdP context struct to setup modem cellular connection
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_pdp_context, command_result, 1, STRUCT_OUT(PdpContext, x)) \
ESP_MODEM_DECLARE_DCE_COMMAND(set_pdp_context, command_result, 1, STRUCT_OUT(PdpContext, p1)) \
\
/**
* @brief Switches to the command mode
@ -130,21 +132,21 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_cmux, command_result, 0) \
* @param[out] imsi Module's IMSI number
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_imsi, command_result, 1, STRING_OUT(x, imsi)) \
ESP_MODEM_DECLARE_DCE_COMMAND(get_imsi, command_result, 1, STRING_OUT(p1, imsi)) \
\
/**
* @brief Reads the IMEI number
* @param[out] imei Module's IMEI number
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_imei, command_result, 1, STRING_OUT(x, imei)) \
ESP_MODEM_DECLARE_DCE_COMMAND(get_imei, command_result, 1, STRING_OUT(p1, imei)) \
\
/**
* @brief Reads the module name
* @param[out] name module name
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_module_name, command_result, 1, STRING_OUT(x, name)) \
ESP_MODEM_DECLARE_DCE_COMMAND(get_module_name, command_result, 1, STRING_OUT(p1, name)) \
\
/**
* @brief Sets the modem to data mode
@ -158,7 +160,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_data_mode, command_result, 0) \
* @param[out] ber channel bit error rate
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_signal_quality, command_result, 2, INT_OUT(x, rssi), INT_OUT(y, ber)) \
ESP_MODEM_DECLARE_DCE_COMMAND(get_signal_quality, command_result, 2, INT_OUT(p1, rssi), INT_OUT(p2, ber)) \
\
/**
* @brief Sets HW control flow
@ -166,7 +168,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(get_signal_quality, command_result, 2, INT_OUT(x,
* @param[in] dte_flow 0=none, 2=CTS hw flow control of DTE
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_flow_control, command_result, 2, INT_IN(x, dce_flow), INT_IN(y, dte_flow)) \
ESP_MODEM_DECLARE_DCE_COMMAND(set_flow_control, command_result, 2, INT_IN(p1, dce_flow), INT_IN(p2, dte_flow)) \
\
/**
* @brief Hangs up current data call
@ -181,7 +183,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(hang_up, command_result, 0) \
* @param[out] bcl 1-100% battery capacity, -1-Not available
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_battery_status, command_result, 3, INT_OUT(x, voltage), INT_OUT(y, bcs), INT_OUT(z, bcl)) \
ESP_MODEM_DECLARE_DCE_COMMAND(get_battery_status, command_result, 3, INT_OUT(p1, voltage), INT_OUT(p2, bcs), INT_OUT(p3, bcl)) \
\
/**
* @brief Power down the module
@ -193,14 +195,95 @@ ESP_MODEM_DECLARE_DCE_COMMAND(power_down, command_result, 0) \
* @brief Reset the module
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(reset, command_result, 0)\
ESP_MODEM_DECLARE_DCE_COMMAND(reset, command_result, 0) \
\
/**
* @brief Configures the baudrate
* @param[in] baud Desired baud rate of the DTE
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_baud, command_result, 1, INT_IN(x, baud))
ESP_MODEM_DECLARE_DCE_COMMAND(set_baud, command_result, 1, INT_IN(p1, baud)) \
\
/**
* @brief Force an attempt to connect to a specific operator
* @param[in] mode mode of attempt
* mode=0 - automatic
* mode=1 - manual
* mode=2 - deregister
* mode=3 - set format for read operation
* mode=4 - manual with fallback to automatic
* @param[in] format what format the operator is given in
* format=0 - long format
* format=1 - short format
* format=2 - numeric
* @param[in] oper the operator to connect to
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_operator, command_result, 3, INT_IN(p1, mode), INT_IN(p2, format), STRING_IN(p3, oper)) \
\
/**
* @brief Attach or detach from the GPRS service
* @param[in] state 1-attach 0-detach
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_network_attachment_state, command_result, 1, INT_IN(p1, state)) \
\
/**
* @brief Get network attachment state
* @param[out] state 1-attached 0-detached
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_network_attachment_state, command_result, 1, INT_OUT(p1, state)) \
\
/**
* @brief What mode the radio should be set to
* @param[in] state state 1-full 0-minimum ...
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_radio_state, command_result, 1, INT_IN(p1, state)) \
\
/**
* @brief Get current radio state
* @param[out] state 1-full 0-minimum ...
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_radio_state, command_result, 1, INT_OUT(p1, state)) \
\
/**
* @brief Set network mode
* @param[in] mode preferred mode
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_network_mode, command_result, 1, INT_IN(p1, mode)) \
\
/**
* @brief Preferred network mode (CAT-M and/or NB-IoT)
* @param[in] mode preferred selection
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_preferred_mode, command_result, 1, INT_IN(p1, mode)) \
\
/**
* @brief Set network bands for CAT-M or NB-IoT
* @param[in] mode CAT-M or NB-IoT
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_network_bands, command_result, 3, STRING_IN(p1, mode), INTEGER_LIST_IN(p2, bands), INT_IN(p3, size)) \
\
/**
* @brief Show network system mode
* @param[out] mode current network mode
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_network_system_mode, command_result, 1, INT_OUT(p1, mode)) \
\
/**
* @brief GNSS power control
* @param[out] mode power mode (0 - off, 1 - on)
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_gnss_power_mode, command_result, 1, INT_IN(p1, mode)) \
\
#ifdef GENERATE_DOCS
@ -213,7 +296,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_baud, command_result, 1, INT_IN(x, baud))
#define _ARG(param, name) name
// --- DCE command documentation starts here ---
#ifdef __cplusplus
class esp_modem::DCE: public DCE_T<GenericModule> {
class esp_modem::DCE : public DCE_T<GenericModule> {
public:
using DCE_T<GenericModule>::DCE_T;
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, TEMPLATE_ARG, ...) return_type name (__VA_ARGS__);

View File

@ -0,0 +1,68 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#define ESP_MODEM_VFS_DEFAULT_UART_CONFIG(name) { \
.dev_name = (name), \
.uart = { \
.port_num = UART_NUM_1, \
.data_bits = UART_DATA_8_BITS, \
.stop_bits = UART_STOP_BITS_1, \
.parity = UART_PARITY_DISABLE, \
.flow_control = ESP_MODEM_FLOW_CONTROL_NONE,\
.baud_rate = 115200, \
.tx_io_num = 25, \
.rx_io_num = 26, \
.rts_io_num = 27, \
.cts_io_num = 23, \
.rx_buffer_size = 4096, \
.tx_buffer_size = 512, \
.event_queue_size = 0, \
}, \
}
/**
* @brief UART init struct for VFS
*/
struct esp_modem_vfs_uart_creator {
const char *dev_name; /*!< VFS device name, e.g. /dev/uart/n */
const struct esp_modem_uart_term_config uart; /*!< UART driver init struct */
};
/**
* @brief UART init struct for VFS
*/
struct esp_modem_vfs_socket_creator {
const char *host_name; /*!< VFS socket: host name (or IP address) */
int port; /*!< VFS socket: port number */
};
/**
* @brief Creates a socket VFS and configures the DTE struct
*
* @param config Socket config option, basically host + port
* @param created_config reference to the VFS portion of the DTE config to be set up
* @return true on success
*/
bool vfs_create_socket(struct esp_modem_vfs_socket_creator *config, struct esp_modem_vfs_term_config *created_config);
/**
* @brief Creates a uart VFS and configures the DTE struct
*
* @param config Uart config option, basically file name and console options
* @param created_config reference to the VFS portion of the DTE config to be set up
* @return true on success
*/
bool vfs_create_uart(struct esp_modem_vfs_uart_creator *config, struct esp_modem_vfs_term_config *created_config);

View File

@ -11,8 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MDNS_HOST_ESP_EVENT_H
#define MDNS_HOST_ESP_EVENT_H
#pragma once
#include <stdint.h>
#include "esp_netif.h"
@ -38,4 +37,4 @@ esp_err_t esp_event_handler_register(const char * event_base, int32_t event_id,
esp_err_t esp_event_handler_unregister(const char * event_base, int32_t event_id, void* event_handler);
#endif //MDNS_HOST_ESP_EVENT_H
typedef void * QueueHandle_t;

View File

@ -11,8 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MDNS_HOST_ESP_EVENT_BASE_H
#define MDNS_HOST_ESP_EVENT_BASE_H
#pragma once
typedef enum {
WIFI_EVENT_STA_CONNECTED, /**< ESP32 station connected to AP */
@ -25,4 +24,3 @@ typedef enum {
typedef void * esp_event_base_t;
#endif //MDNS_HOST_ESP_EVENT_BASE_H

View File

@ -3,18 +3,20 @@ set(LWIP_CONTRIB_DIR "$ENV{LWIP_CONTRIB_PATH}")
set(lwipcontribportunix_SRCS ${LWIP_CONTRIB_DIR}/ports/unix/port/sys_arch.c)
include(${LWIP_DIR}/src/Filelists.cmake)
if(NOT CMAKE_BUILD_EARLY_EXPANSION)
set (LWIP_INCLUDE_DIRS
include(${LWIP_DIR}/src/Filelists.cmake)
set (LWIP_INCLUDE_DIRS
"${LWIP_DIR}/src/include"
"${LWIP_CONTRIB_DIR}/ports/unix/port/include")
list(REMOVE_ITEM lwipnoapps_SRCS "${LWIP_DIR}/src/netif/slipif.c")
list(REMOVE_ITEM lwipnoapps_SRCS "${LWIP_DIR}/src/core/ip4.c")
list(REMOVE_ITEM lwipnoapps_SRCS "${LWIP_DIR}/src/core/ipv6/ip6.c")
list(REMOVE_ITEM lwipnoapps_SRCS "${LWIP_DIR}/src/netif/slipif.c")
list(REMOVE_ITEM lwipnoapps_SRCS "${LWIP_DIR}/src/core/ipv4/ip4.c")
list(REMOVE_ITEM lwipnoapps_SRCS "${LWIP_DIR}/src/core/ipv6/ip6.c")
endif()
idf_component_register(SRCS esp_netif_linux.cpp tun_io.c ip6_stub.c ${lwipnoapps_SRCS} ${lwipcontribportunix_SRCS}
idf_component_register(SRCS esp_netif_linux.cpp tun_io.c ip4_stub.c ip6_stub.c ${lwipnoapps_SRCS} ${lwipcontribportunix_SRCS}
INCLUDE_DIRS include ${LWIP_INCLUDE_DIRS}
PRIV_INCLUDE_DIRS .
REQUIRES esp_system_protocols_linux)

View File

@ -35,8 +35,7 @@ class NetifStorage;
void read_task(NetifStorage *netif);
class NetifStorage: public esp_netif_obj
{
class NetifStorage: public esp_netif_obj {
public:
explicit NetifStorage(const esp_netif_config_t *config) : esp_netif_obj(), exit(false)
{
@ -91,46 +90,9 @@ public:
extern "C" esp_netif_t *esp_netif_new(const esp_netif_config_t *config)
{
return new NetifStorage(config);
// struct ifreq ifr = { };
// esp_netif_t * netif = netif_storage;
// if (netif == NULL) {
// return NULL;
// }
// if ((netif->fd = open(config->dev_name, O_RDWR)) == -1) {
// ESP_LOGE(TAG, "Cannot open %s", config->dev_name);
// goto cleanup;
// }
// ifr.ifr_flags = IFF_TUN;
// strncpy(ifr.ifr_name, config->if_name, IFNAMSIZ);
//
// if (ioctl(netif->fd, TUNSETIFF, (void *)&ifr) == -1) {
// ESP_LOGE(TAG, "Cannot set ioctl TUNSETIFF %m");
// goto cleanup;
// }
// ioctl(netif->fd, TUNSETNOCSUM, 1);
//
// netif->in_buf = new uint8_t[BUF_SIZE];
// netif->out_buf = new uint8_t[BUF_SIZE];
// if (netif->in_buf == nullptr || netif->out_buf == nullptr) {
// goto cleanup;
// }
//
// if (!ppp_netif_init(netif)) {
// ESP_LOGE(TAG, "Cannot initialize pppos lwip netif %m");
// goto cleanup;
// }
//
// return netif;
//
//cleanup:
// close(netif->fd);
// delete[] netif->in_buf;
// delete[] netif->out_buf;
// delete netif_storage;
// return nullptr;
}
void esp_netif_destroy(esp_netif_t *netif)
{
delete static_cast<NetifStorage*>(netif);
delete static_cast<NetifStorage *>(netif);
}

View File

@ -11,8 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _HOST_ESP_NETIF_H_
#define _HOST_ESP_NETIF_H_
#pragma once
#include <stdint.h>
#include <stdlib.h>
@ -63,5 +62,3 @@ void esp_netif_destroy(esp_netif_t *esp_netif);
#ifdef __cplusplus
}
#endif
#endif // _HOST_ESP_NETIF_H_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_NETIF_IP_ADDR_H_
#define _ESP_NETIF_IP_ADDR_H_
#pragma once
#include <endian.h>
@ -164,5 +163,3 @@ esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr);
#ifdef __cplusplus
}
#endif
#endif //_ESP_NETIF_IP_ADDR_H_

View File

@ -13,10 +13,6 @@
// limitations under the License.
#ifndef _ESP_NETIF_PPP_H_
#define _ESP_NETIF_PPP_H_
#pragma once
#define NETIF_PP_PHASE_OFFSET 0x100
#endif //_ESP_NETIF_PPP_H_

View File

@ -0,0 +1,17 @@
#include "lwip/ip4.h"
err_t
ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
u8_t ttl, u8_t tos,
u8_t proto, struct netif *netif)
{ return ERR_OK; }
struct netif *
ip4_route(const ip4_addr_t *dest)
{ return NULL; }
err_t
ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
u8_t ttl, u8_t tos,
u8_t proto, struct netif *netif)
{ return ERR_OK; }

View File

@ -12,6 +12,7 @@
// limitations under the License.
#pragma once
#include <stdint.h>
typedef int uart_port_t;
typedef int uart_word_length_t;

View File

@ -11,6 +11,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
typedef int esp_err_t;
#define ESP_FAIL -1

View File

@ -11,8 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MDNS_HOST_ESP_LOG_H
#define MDNS_HOST_ESP_LOG_H
#pragma once
#include <stdio.h>
@ -46,4 +45,3 @@ printf(LOG_COLOR_D); printf("(%s) ", TAG); printf(__VA_ARGS__); printf(LOG_RESET
#define ESP_LOGV(TAG, ...) do { \
printf(LOG_COLOR_V); printf("(%s) ", TAG); printf(__VA_ARGS__); printf(LOG_RESET_COLOR "\n"); } while(0)
#endif //MDNS_HOST_ESP_LOG_H

View File

@ -11,9 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MDNS_HOST_ENDIAN_H
#define MDNS_HOST_ENDIAN_H
#pragma once
#include_next "endian.h"
#endif //MDNS_HOST_ENDIAN_H

View File

@ -0,0 +1,8 @@
#!/bin/bash
apt-get update
apt-get -y install doxygen clang python3-pip
python -m pip install breathe recommonmark
pushd components/esp_modem/docs
./generate_docs
popd

View File

@ -12,25 +12,28 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _EXCEPTION_STUB_HPP_
#define _EXCEPTION_STUB_HPP_
#pragma once
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
#define TRY_CATCH_RET_NULL(block) \
#define TRY_CATCH_OR_DO(block, action) \
try { block \
} catch (std::bad_alloc& e) { \
ESP_LOGE(TAG, "Out of memory"); \
return nullptr; \
} catch (esp_err_exception& e) { \
action; \
} catch (::esp_modem::esp_err_exception& e) { \
esp_err_t err = e.get_err_t(); \
ESP_LOGE(TAG, "%s: Exception caught with ESP err_code=%d", __func__, err); \
ESP_LOGE(TAG, "%s", e.what()); \
return nullptr; \
action; \
}
#define TRY_CATCH_RET_NULL(block) TRY_CATCH_OR_DO(block, return nullptr)
#else
#define TRY_CATCH_OR_DO(block, action) \
block
#define TRY_CATCH_RET_NULL(block) \
block
#endif
#endif // _EXCEPTION_STUB_HPP_

View File

@ -0,0 +1,32 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "esp_log.h"
#include "driver/uart.h"
/**
* @brief This is a compatible header, which just takes care of different data ptr type
* across different IDF version in driver/uart
*/
static inline int uart_write_bytes_compat(uart_port_t uart_num, const void* src, size_t size)
{
#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 3
const void *data = src;
#else
auto *data = reinterpret_cast<const char*>(src);
#endif
return uart_write_bytes(uart_num, data, size);
}

View File

@ -12,13 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UART_RESOURCE_HPP_
#define _UART_RESOURCE_HPP_
#pragma once
#include "cxx_include/esp_modem_dte.hpp"
#include "esp_modem_config.h"
struct esp_modem_dte_config;
struct esp_modem_uart_term_config;
namespace esp_modem {
@ -26,13 +25,12 @@ namespace esp_modem {
* @brief Uart Resource is a platform specific struct which is implemented separately for ESP_PLATFORM and linux target
*/
struct uart_resource {
explicit uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue, int fd);
explicit uart_resource(const esp_modem_uart_term_config *config, QueueHandle_t *event_queue, int fd);
~uart_resource();
uart_port_t port{};
};
std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config);
} // namespace esp_modem
#endif // _UART_RESOURCE_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UART_TERMINAL_HPP_
#define _UART_TERMINAL_HPP_
#pragma once
#include "cxx_include/esp_modem_dte.hpp"
@ -25,4 +24,3 @@ std::unique_ptr<Terminal> create_uart_terminal(const esp_modem_dte_config *confi
} // namespace esp_modem
#endif // _UART_TERMINAL_HPP_

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _VFS_TERMINAL_HPP_
#define _VFS_TERMINAL_HPP_
#pragma once
#include "cxx_include/esp_modem_dte.hpp"
@ -24,5 +23,3 @@ namespace esp_modem {
std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config);
} // namespace esp_modem
#endif // _VFS_TERMINAL_HPP_

View File

@ -30,43 +30,53 @@ struct PdpContext;
static const char *TAG = "modem_api";
#endif
std::shared_ptr<DTE> create_uart_dte(const dte_config *config) {
TRY_CATCH_RET_NULL(
auto term = create_uart_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
)
}
std::shared_ptr<DTE> create_vfs_dte(const dte_config *config) {
std::shared_ptr<DTE> create_vfs_dte(const dte_config *config)
{
TRY_CATCH_RET_NULL(
auto term = create_vfs_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
auto term = create_vfs_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
)
}
static inline std::unique_ptr<DCE>
create_modem_dce(dce_factory::Modem m, const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
create_modem_dce(dce_factory::ModemType m, const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
dce_factory::Factory f(m);
TRY_CATCH_RET_NULL(
return f.build_unique(config, std::move(dte), netif);
return f.build_unique(config, std::move(dte), netif);
)
}
std::unique_ptr<DCE> create_SIM7600_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
return create_modem_dce(dce_factory::Modem::SIM7600, config, std::move(dte), netif);
std::unique_ptr<DCE> create_SIM7600_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::SIM7600, config, std::move(dte), netif);
}
std::unique_ptr<DCE> create_SIM800_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
return create_modem_dce(dce_factory::Modem::SIM800, config, std::move(dte), netif);
std::unique_ptr<DCE> create_SIM7070_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::SIM7070, config, std::move(dte), netif);
}
std::unique_ptr<DCE> create_BG96_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
return create_modem_dce(dce_factory::Modem::BG96, config, std::move(dte), netif);
std::unique_ptr<DCE> create_SIM7000_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::SIM7000, config, std::move(dte), netif);
}
std::unique_ptr<DCE> create_generic_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
return create_modem_dce(dce_factory::Modem::GenericModule, config, std::move(dte), netif);
std::unique_ptr<DCE> create_SIM800_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::SIM800, config, std::move(dte), netif);
}
std::unique_ptr<DCE> create_BG96_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::BG96, config, std::move(dte), netif);
}
std::unique_ptr<DCE> create_generic_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::GenericModule, config, std::move(dte), netif);
}
} // namespace esp_modem

View File

@ -0,0 +1,39 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cassert>
#include "esp_log.h"
#include "cxx_include/esp_modem_dte.hpp"
#include "uart_terminal.hpp"
#include "vfs_termial.hpp"
#include "cxx_include/esp_modem_api.hpp"
#include "cxx_include/esp_modem_dce_factory.hpp"
#include "esp_modem_config.h"
#include "exception_stub.hpp"
namespace esp_modem {
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
static const char *TAG = "modem_api_target";
#endif
std::shared_ptr<DTE> create_uart_dte(const dte_config *config)
{
TRY_CATCH_RET_NULL(
auto term = create_uart_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
)
}
} // namespace esp_modem

Some files were not shown because too many files have changed in this diff Show More