Compare commits

...

76 Commits

Author SHA1 Message Date
6a94e61a7e Merge pull request #288 from david-cermak/bump/mdns
bump(mdns): 1.0.9 -> 1.1.0
2023-04-28 20:36:35 +02:00
c8fe4092c4 bump(mdns): 1.0.9 -> 1.1.0
1.1.0
Features
- Decouple main module from mdns-networking (d238e93)
Bug Fixes
- Use idf-build-apps package for building mdns (1a0a41f)
- socket networking to init interfaces properly (ee9b04f)
- Removed unused internal lock from mdns_server struct (a06fb77)
- Resolve conflicts only on self hosted items (e69a9eb, #185)
- Fix memory issues reported by valgrind (0a682e7)
Updated
- docs(common): updated component and example links (f48d9b2)
- Add APIs to look up delegated services (87dcd7d)
- Fix deadly mdns crash (4fa3023)
- docs(common): improving documentation (ca3fce0)
- append all ipv6 address in mdns answer (5ed3e9a)
- test(mdns): Host tests to use IDF's esp_event_stub (537d170)
2023-04-28 19:32:47 +02:00
31187b7d17 Merge pull request #283 from espressif/esp_modem/fix_build
fix(esp_modem): fix esp_modem build issue
2023-04-27 20:31:19 +04:00
ab94566995 fix(esp_modem): fix esp_modem build issue 2023-04-27 12:25:59 +04:00
f67511c2c1 Merge pull request #275 from gabsuren/docs/esp_modem_docs
docs(esp_modem): updated documents to show missed topics
2023-04-27 10:56:12 +04:00
05348534a6 docs(esp_modem): updated documents to show missed topics 2023-04-26 16:24:30 +04:00
18ea910f02 Merge pull request #279 from david-cermak/feat/auto_tag
ci(common): Support for tagging and releasing in CI
2023-04-25 16:31:11 +02:00
62be981c92 ci(common): Fail CI if the PR to too much behind origin
And removes the docs generation/deploy part
2023-04-25 16:27:05 +02:00
6daf6c6ba6 ci(common): Support for tagging and releasing in CI 2023-04-25 13:54:44 +02:00
b0d3b41aae Merge pull request #277 from gabsuren/docs/update_links
docs(common): updated component and example links
2023-04-20 12:01:22 +04:00
f48d9b2fcf docs(common): updated component and example links 2023-04-19 11:58:05 +04:00
6c299c068b Merge pull request #274 from david-cermak/bugfix/ci_mdns_all_targets
mdns: Build all targets and releases
2023-04-18 10:38:46 +02:00
ea5d3cee29 Merge pull request #268 from wqx6/search_delegated_service
mdns: Add APIs to lookup delegated services (IDFGH-9790)
2023-04-18 10:38:27 +02:00
7330597586 Merge pull request #270 from 0xFEEDC0DE64/fix_mdns_crash
Fix deadly mdns crash (IDFGH-9800)
2023-04-18 10:37:11 +02:00
1a0a41fa2d fix(mdns): Use idf-build-apps package for building mdns 2023-04-17 13:44:18 +02:00
2f7cbd16db ci(common): Fix pre-commit manual run 2023-04-17 13:43:14 +02:00
87dcd7dc7d mdns: Add APIs to look up delegated services 2023-04-17 19:35:41 +08:00
8e5a27f4b7 docs: fixed broken link in README.md 2023-04-10 18:38:23 +04:00
6528f446bc docs: fixed broken link on README.md 2023-04-07 16:43:43 +04:00
4fa3023ea2 Fix deadly mdns crash 2023-04-05 16:13:07 +02:00
10f8200564 Merge pull request #267 from gabsuren/esp_mqtt_cxx/updated_docs_and_yml_file
docs(esp_mqtt_cxx): updated documentation and deployment *yml file
2023-04-05 11:51:28 +04:00
a547ec8147 docs(esp_mqtt_cxx): updated documentation and deployment file 2023-04-05 11:42:59 +04:00
db0e20f446 Merge pull request #256 from gabsuren/docs/documentation_improving
docs: Improving documentation (IDF-7064)
2023-03-31 12:07:09 +04:00
ca3fce003e docs(common): improving documentation
- update esp_modem to use esp_docs
- migrated docs from github pages to docs.espressif.com
2023-03-31 12:04:46 +04:00
f6ff132eb1 Merge pull request #259 from 0xFEEDC0DE64/fix_websocket_error_spacings
Fix weird error message spacings (IDFGH-9704)
2023-03-23 17:57:12 +01:00
8bb207e9bb Fix weird error message spacings 2023-03-23 11:44:51 +01:00
76047a4cc6 Merge pull request #137 from david-cermak/mdns/isolate_networking
mdns: Decouple networking from the main mdns module
2023-03-22 14:40:49 +01:00
ee9b04f598 fix(mdns): socket networking to init interfaces properly 2023-03-22 12:17:09 +01:00
d238e9311b feat(mdns): Decouple main module from mdns-networking
Removed sharing the data via the global variable `_mdns_server`, added
API `mdns_is_netif_ready()`
2023-03-22 12:16:28 +01:00
a838af46a6 Merge pull request #251 from xieqinan/feature/append-all-ipv6-address-in-mdns-answer
mdns: append all ipv6 address in mdns answer (IDFGH-9646)
2023-03-22 08:16:38 +01:00
5ed3e9a6a1 mdns: append all ipv6 address in mdns answer 2023-03-22 12:00:38 +08:00
5b3346f5c5 Merge pull request #225 from david-cermak/bugfix/mdns_wrong_name_collision
fix(mdns): Incorrect name collision
2023-03-20 17:24:47 +01:00
a06fb7714b fix(mdns): Removed unused internal lock from mdns_server struct 2023-03-20 16:55:49 +01:00
e69a9ebb3d fix(mdns): Resolve conflicts only on self hosted items
Skip solving conflicts for delegated names and delegated services

Closes https://github.com/espressif/esp-protocols/issues/185
2023-03-20 16:55:49 +01:00
2e607e8ffb Merge pull request #257 from david-cermak/fix/mdns_valgrind
fix(mdns): Fix memory issues reported by valgrind
2023-03-20 16:49:36 +01:00
0a9765626b Merge pull request #255 from david-cermak/feat/modem_cz_bump
esp_modem: version 1.0.0 (plus cz-bump config)
2023-03-20 12:33:32 +01:00
537d170f1d test(mdns): Host tests to use IDF's esp_event_stub
Also fixes one minor from esp_netif_linux implementation
2023-03-20 12:17:36 +01:00
0a682e7f12 fix(mdns): Fix memory issues reported by valgrind
* Read after the allocated area (which may lead to subsequent
mdns name corruption)
* Potentially uninit variable used in condition
2023-03-19 20:58:10 +01:00
afb69308df fix(modem): Example to use 1.0.0 2023-03-16 20:47:59 +01:00
284cdeb2ed Merge pull request #254 from lhauswald/feature/mqtt_client_certificate
MQTT: complete client authentication configuration (IDFGH-9656)
2023-03-16 20:35:23 +01:00
97d52495d4 bump(modem): 0.1.28 -> 1.0.0 2023-03-16 20:19:00 +01:00
423e965c88 fix(common): Changelog to correctly pick references
Also added .cz config for modem components
2023-03-16 20:19:00 +01:00
e762ada551 Merge pull request #156 from david-cermak/feature/modem_example_at_mqtt
feat(esp_modem): Add mqtt example in  AT-only mode
2023-03-16 20:17:32 +01:00
31d4323f53 fix(modem): AT-only example: support MQTT over TLS on BG96 2023-03-16 19:49:10 +01:00
97831c62b1 fix(modem): AT-only example: added into CI 2023-03-16 19:48:34 +01:00
ceedcfca23 fix(modem): AT-only example: initial adaptation to BG96
Plus rework a little to support implementation of multiple devices
2023-03-16 19:45:43 +01:00
7547267336 feat(modem): Add mqtt example in AT-only mode
Similar to pppos-client, but without PPP mode.
This uses standard mqtt client and a loopback service that forwards the
TCP traffic from localhost to the modem and vice-versa.
(next step is to create a dedicated tcp-transport layer for modem)
Console example uses DCE commandable to demontrate how to handle URC
2023-03-16 19:42:29 +01:00
bf114d3624 feat(modem): DTE to support sending and receiving raw data
MAJOR CHANGE: Enable DTE to redefine on_read() and write(cmd) directly
2023-03-16 19:39:13 +01:00
574738b8d3 Merge pull request #252 from tore-espressif/feature/esp_modem/usb_examples
esp_modem: Update examples for USB v1.1
2023-03-16 13:32:29 +01:00
ee09ff45e5 feat(mqtt_cxx): configure client authentication via certificate/key or secure element 2023-03-16 09:42:43 +01:00
895a72b27d Merge pull request #249 from david-cermak/feat/cz_bump
mdns: Bump config to auto-generate change log
2023-03-16 09:40:45 +01:00
bf32e452d6 fix(modem): warning in ap-2-pppos example when using lwip/napt
Latest IDF added new napt API that support enabling NAPT based on netif
pointer. Need to include "lwip/netif.h"
2023-03-16 09:26:30 +01:00
4c7720a2c1 ci(common): Run all test on push event
Added a description about the release process to the contributing guide
2023-03-16 08:56:18 +01:00
c92ce075fd bump(mdns): 1.0.8 -> 1.0.9 2023-03-16 08:18:33 +01:00
f29719fa0b ci(common): force scoping commit messages with components
Add simple changelog generator and mdns tag formatter
2023-03-16 08:18:33 +01:00
2d1990614a Merge pull request #253 from david-cermak/bufix/precommit_check_only_pr
fix(ci): Run pre-commit checker only on PRs
2023-03-15 19:27:01 +01:00
2863e94a11 fix(ci): Run pre-commit checker only on PRs
Regression from a089e0d680 Merged as https://github.com/espressif/esp-protocols/pull/242
2023-03-15 19:11:27 +01:00
ba45e9a07e Merge pull request #242 from david-cermak/bugfix/modem_strip_idf_4.1
fix(esp_modem): run CI build job for all targets
2023-03-15 18:55:26 +01:00
610372f5a7 esp_modem: Update examples for USB v1.1 2023-03-15 17:13:37 +01:00
13eca128fb fix(ci): trigger PR jobs based on labels 2023-03-15 15:38:06 +01:00
c492d87316 Merge pull request #247 from david-cermak/fix/add_missing_changelogs
fix(common): Reintroduce missing CHANGELOGs
2023-03-13 19:38:15 +01:00
200cbb3383 fix(common): Reintroduce missing CHANGELOGs
Closes https://github.com/espressif/esp-protocols/issues/235
2023-03-13 12:58:25 +01:00
a96f17d9a1 Merge pull request #236 from gabsuren/CI/conventional_commits
ci: added conventionl commit pre-commit hook
2023-03-10 18:56:26 +01:00
cbda15724c ci: regroup tests per components and purpose 2023-03-08 17:33:48 +01:00
d0814bf963 fix(esp_modem): Use default UART CLK source
Some targets don't support UART_SCLK_APB (e.g. esp32c2)
This change is applicable only for IDFv5.0 and later, as older version
didn't define UART_SCLK_DEFAULT.

Closes https://github.com/espressif/esp-protocols/issues/241
2023-03-08 11:51:31 +01:00
a089e0d680 fix(esp_modem): run CI build job for all targets
Also
* removed IDFv4.1 from tests
* added common build_apps.py utility for finding/building apps
2023-03-08 11:51:25 +01:00
ef4985cce6 Merge pull request #243 from tore-espressif/feature/esp_modem/dual_dte
esp_modem: Dual DTE support
2023-03-08 11:01:16 +01:00
01c26c82fa esp_modem: Dual DTE support
Modems can expose 2 terminals, which can be used simultaneously.
One for AT commands, the other one for data.
2023-03-07 13:35:34 +01:00
08f1f0175d Merge pull request #228 from gabsuren/CI/update_websocket_version
websocket: Updated version to 1.0.0
2023-03-06 12:36:30 +04:00
a6817e0c7f ci: Add conventionl commit pre-commit hook 2023-03-03 12:38:27 +04:00
a2050ac041 Merge pull request #233 from tom-borcin/feature/add_issue_templates
Add issue templates
2023-03-02 17:19:59 +01:00
6015c19c31 Merge pull request #239 from kumekay/feature/add_url_license
Add homepage URL and License to all components (IDFGH-9521)
2023-03-02 17:17:00 +01:00
5df8fdb713 Add input for component version 2023-03-02 15:38:10 +01:00
ef3f0ee688 Add homepage URL and License to all components 2023-03-02 12:35:17 +01:00
996fef7fcf esp_websocket_client: Updated version to 1.0.0
Updated tests to run agains release-v5.0
2023-02-28 19:00:46 +04:00
9f87a8ca77 Add issue templates 2023-02-24 15:53:31 +01:00
151 changed files with 5129 additions and 1295 deletions

View File

@ -137,4 +137,4 @@ show_source = True
statistics = True
exclude =
components/asio/docs/conf_common.py
docs/asio/conf_common.py

51
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@ -0,0 +1,51 @@
name: Installation or build bug report
description: Report installation or build bugs
labels: ['Type: Bug']
body:
- type: checkboxes
id: checklist
attributes:
label: Answers checklist.
description: Before submitting a new issue, please follow the checklist and try to find the answer.
options:
- label: I have read the documentation for [esp-protocols components](https://espressif.github.io/esp-protocols/) and the issue is not addressed there.
required: true
- label: I have updated my esp-protocols branch (master or release) to the latest version and checked that the issue is present there.
required: true
- label: I have searched the issue tracker for a similar issue and not found a similar issue.
required: true
- type: dropdown
id: component
attributes:
label: What component are you using? If you choose Other, provide details in More Information.
multiple: false
options:
- ASIO port
- esp_modem
- esp_websocket_client
- mDNS
- Other
validations:
required: true
- type: input
id: component_id
attributes:
label: component version
description: Which component version does this issue occur on? (see your `idf_component.yml`)
placeholder: ex. 1.0.0
- type: input
id: idf_version
attributes:
label: IDF version.
description: On which IDF version does this issue occur on? Run `git describe --tags` to find it.
placeholder: ex. v3.2-dev-1148-g96cd3b75c
validations:
required: true
- type: textarea
id: more-info
attributes:
label: More Information.
description: Do you have any other information from investigating this?
placeholder: ex. I tried on my friend's Windows 10 PC and the command works there.
validations:
required: false

14
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: esp-protocols documentation
url: https://espressif.github.io/esp-protocols/
about: Documenation for esp-protocols components.
- name: ESP-IDF Programming Guide
url: https://docs.espressif.com/projects/esp-idf/en/latest/
about: Documentation for configuring and using ESP-IDF.
- name: Espressif documentation page
url: https://www.espressif.com/en/support/download/documents
about: Hardware documentation (datasheets, Technical Reference Manual, etc).
- name: Forum
url: https://esp32.com
about: For questions about using ESP-IDF and/or ESP32 series chips. Please submit all questions starting "How do I..." here.

View File

@ -0,0 +1,33 @@
name: Feature request
description: Suggest an idea or new component for this project.
labels: ['Type: Feature Request']
body:
- type: markdown
attributes:
value: |
* We welcome any ideas or feature requests! Its helpful if you can explain exactly why the feature would be useful.
* There are usually some outstanding feature requests in the [existing issues list](https://github.com/espressif/esp-protocols/labels/Type%3A%20Feature%20Request), feel free to add comments to them.
- type: textarea
id: problem-related
attributes:
label: Is your feature request related to a problem?
description: Please provide a clear and concise description of what the problem is.
placeholder: ex. I'm always frustrated when ...
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like.
description: Please provide a clear and concise description of what you want to happen.
placeholder: ex. When building my application ...
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered.
description: Please provide a clear and concise description of any alternative solutions or features you've considered.
placeholder: ex. Choosing other approach wouldn't work, because ...
- type: textarea
id: context
attributes:
label: Additional context.
description: Please add any other context or screenshots about the feature request here.
placeholder: ex. This would work only when ...

23
.github/ISSUE_TEMPLATE/other-issue.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: General issue report
description: File an issue report
body:
- type: checkboxes
id: checklist
attributes:
label: Answers checklist.
description: Before submitting a new issue, please follow the checklist and try to find the answer.
options:
- label: I have read the documentation for [esp-protocols components](https://espressif.github.io/esp-protocols/) and the issue is not addressed there.
required: true
- label: I have updated my esp-protocols branch (master or release) to the latest version and checked that the issue is present there.
required: true
- label: I have searched the issue tracker for a similar issue and not found a similar issue.
required: true
- type: textarea
id: issue
attributes:
label: General issue report
description: Your issue report goes here.
placeholder: ex. How do I...
validations:
required: true

View File

@ -0,0 +1,100 @@
name: "asio: build/target-tests"
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened, labeled]
jobs:
build_asio:
if: contains(github.event.pull_request.labels.*.name, 'asio') || github.event_name == 'push'
name: Build
strategy:
matrix:
idf_ver: ["latest", "release-v5.0"]
idf_target: ["esp32", "esp32s2"]
example: ["asio_chat", "async_request", "socks4", "ssl_client_server", "tcp_echo_server", "udp_echo_server"]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
env:
TEST_DIR: components/asio/examples
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
working-directory: ${{ env.TEST_DIR }}/${{ matrix.example }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
test -f sdkconfig.ci && cat sdkconfig.ci >> sdkconfig.defaults || echo "No sdkconfig.ci"
idf.py set-target ${{ matrix.idf_target }}
idf.py build
- name: Merge binaries with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }} for ${{ matrix.example }}
working-directory: ${{ env.TEST_DIR }}/${{ matrix.example }}/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@v3
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.example }}
path: |
${{ env.TEST_DIR }}/${{ matrix.example }}/build/bootloader/bootloader.bin
${{ env.TEST_DIR }}/${{ matrix.example }}/build//partition_table/partition-table.bin
${{ env.TEST_DIR }}/${{ matrix.example }}/build/*.bin
${{ env.TEST_DIR }}/${{ matrix.example }}/build/*.elf
${{ env.TEST_DIR }}/${{ matrix.example }}/build/flasher_args.json
${{ env.TEST_DIR }}/${{ matrix.example }}/build/config/sdkconfig.h
${{ env.TEST_DIR }}/${{ matrix.example }}/build/config/sdkconfig.json
if-no-files-found: error
target_tests_asio:
# Skip running on forks since it won't have access to secrets
if: |
github.repository == 'espressif/esp-protocols' &&
( contains(github.event.pull_request.labels.*.name, 'asio') || github.event_name == 'push' )
name: Target tests
strategy:
matrix:
idf_ver: ["latest", "release-v5.0"]
idf_target: ["esp32"]
example: ["asio_chat", "tcp_echo_server", "udp_echo_server", "ssl_client_server"]
needs: build_asio
runs-on:
- self-hosted
- ESP32-ETHERNET-KIT
env:
TEST_DIR: components/asio/examples
steps:
- name: Clear repository
run: sudo rm -fr $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.example }}
path: ${{ env.TEST_DIR }}/${{ matrix.example }}/build
- name: Install Python packages
env:
PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple"
run: |
sudo apt-get install -y dnsutils
- name: Download Example Test to target ${{ matrix.config }}
run: |
python -m esptool --chip ${{ matrix.idf_target }} write_flash 0x0 ${{ env.TEST_DIR }}/${{ matrix.example }}/build/flash_image.bin
- name: Run Example Test ${{ matrix.example }} on target
working-directory: ${{ env.TEST_DIR }}/${{ matrix.example }}
run: |
python -m pytest --log-cli-level DEBUG --junit-xml=./examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.config }}.xml --target=${{ matrix.idf_target }}
- uses: actions/upload-artifact@v3
if: always()
with:
name: examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.example }}
path: ${{ env.TEST_DIR }}/${{ matrix.example }}/*.xml

View File

@ -1,92 +0,0 @@
name: Code Coverage Analyzer
on: [push, pull_request]
jobs:
gcovr_analyzer_esp_modem:
name: Run gcovr on esp modem host test
runs-on: ubuntu-22.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
COMP_DIR: esp-protocols/components/esp_modem
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
path: esp-protocols
persist-credentials: false
- name: Build and Test
shell: bash
run: |
apt-get update
apt-get update && apt-get install -y gcc-8 g++-8 python3-pip
apt-get install -y rsync
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8
export DEBIAN_FRONTEND=noninteractive
export LWIP_PATH=`pwd`/${{ env.lwip }}
export LWIP_CONTRIB_PATH=`pwd`/${{ env.lwip_contrib }}
. ${IDF_PATH}/export.sh
${{ env.COMP_DIR }}/test/host_test/env.sh $lwip $lwip_uri $lwip_contrib
cd $GITHUB_WORKSPACE/${{ env.COMP_DIR }}/test/host_test
cat sdkconfig.ci.coverage >> sdkconfig.defaults
idf.py build
./build/host_modem_test.elf
- name: Run gcovr
shell: bash
run: |
python -m pip install gcovr
cd $GITHUB_WORKSPACE/${{ env.COMP_DIR }}
gcov-8 `find . -name "esp_modem*gcda" -printf '%h\n' | head -n 1`/*
gcovr --gcov-ignore-parse-errors -g -k -r . --html index.html -x esp_modem_coverage.xml
mkdir docs_gcovr
cp $GITHUB_WORKSPACE/${{ env.COMP_DIR }}/index.html docs_gcovr
touch docs_gcovr/.nojekyll
- name: Code Coverage Summary Report
uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: esp-protocols/**/esp_modem_coverage.xml
badge: true
fail_below_min: false
format: markdown
hide_branch_rate: false
hide_complexity: false
indicators: true
output: both
thresholds: '60 80'
- name: Write to Job Summary
run: cat code-coverage-results.md >> $GITHUB_STEP_SUMMARY
- name: Upload artifacts
uses: actions/upload-artifact@v3
if: always()
with:
name: docs_gcovr
path: |
${{ env.COMP_DIR }}/docs_gcovr
if-no-files-found: error
# show_report_data:
# name: Publish-Results
# if: github.ref == 'refs/heads/master' || github.repository != 'espressif/esp-protocols'
# runs-on: ubuntu-22.04
# needs: gcovr_analyzer_esp_modem
# steps:
# - name: Checkout 🛎️
# uses: actions/checkout@v3
# with:
# persist-credentials: false
# - name: Download Artifacts
# uses: actions/download-artifact@v1
# with:
# name: docs_gcovr
#
# - name: Deploy generated docs
# uses: JamesIves/github-pages-deploy-action@v4
# with:
# branch: gh-pages
# folder: 'docs_gcovr'

View File

@ -1,63 +0,0 @@
name: Host test
on: [push, pull_request]
jobs:
host_test_esp_modem:
name: esp-modem Build and Test on Host
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
COMP_DIR: esp-protocols/components/esp_modem
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 }}
. ${IDF_PATH}/export.sh
$GITHUB_WORKSPACE/${{ env.COMP_DIR }}/test/host_test/env.sh $lwip $lwip_uri $lwip_contrib
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
host_test_mdns:
name: mdns Build and Test on Host
runs-on: ubuntu-20.04
container: espressif/idf:latest
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 dnsutils gcc g++
. ${IDF_PATH}/export.sh
cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/tests/host_test
idf.py build
./build/mdns_host.elf &
dig +short -p 5353 @224.0.0.251 myesp.local > ip.txt
cat ip.txt | xargs dig +short -p 5353 @224.0.0.251 -x
cat ip.txt

View File

@ -0,0 +1,84 @@
name: "mdns: build/target-tests"
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened, labeled]
jobs:
build_mdns:
if: contains(github.event.pull_request.labels.*.name, 'mdns') || github.event_name == 'push'
name: Build
strategy:
matrix:
idf_ver: ["latest", "release-v5.0"]
test: [ { app: example, path: "examples" }, { app: unit_test, path: "tests/unit_test" }, { app: test_app, path: "tests/test_apps" } ]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
- name: Build ${{ matrix.test.app }} with IDF-${{ matrix.idf_ver }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
python -m pip install idf-build-apps
# Build default configs for all targets
python ./ci/build_apps.py components/mdns/${{ matrix.test.path }} -r default -m components/mdns/.build-test-rules.yml -d
# Build specific configs for test targets
python ./ci/build_apps.py components/mdns/${{ matrix.test.path }}
cd components/mdns/${{ matrix.test.path }}
for dir in `ls -d build_esp32_*`; do
$GITHUB_WORKSPACE/ci/clean_build_artifacts.sh `pwd`/$dir
zip -qur artifacts.zip $dir
done
- uses: actions/upload-artifact@v3
with:
name: mdns_bin_esp32_${{ matrix.idf_ver }}_${{ matrix.test.app }}
path: components/mdns/${{ matrix.test.path }}/artifacts.zip
if-no-files-found: error
target_tests_mdns:
# Skip running on forks since it won't have access to secrets
if: |
github.repository == 'espressif/esp-protocols' &&
( contains(github.event.pull_request.labels.*.name, 'mdns') || github.event_name == 'push' )
name: Target Example and Unit tests
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32"]
test: [ { app: example, path: "examples" }, { app: unit_test, path: "tests/unit_test" }, { app: test_app, path: "tests/test_apps" } ]
needs: build_mdns
runs-on:
- self-hosted
- ESP32-ETHERNET-KIT
steps:
- name: Clear repository
run: sudo rm -fr $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: mdns_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
path: components/mdns/${{ matrix.test.path }}/ci/
- name: Install Python packages
env:
PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple"
run: |
sudo apt-get install -y dnsutils
- name: Run ${{ matrix.test.app }} application on ${{ matrix.idf_target }}
working-directory: components/mdns/${{ matrix.test.path }}
run: |
unzip ci/artifacts.zip -d ci
for dir in `ls -d ci/build_*`; do
rm -rf build sdkconfig.defaults
mv $dir build
python -m pytest --log-cli-level DEBUG --junit-xml=./results_${{ matrix.test.app }}_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${dir#"ci/build_"}.xml --target=${{ matrix.idf_target }}
done
- uses: actions/upload-artifact@v3
if: always()
with:
name: results_${{ matrix.test.app }}_${{ matrix.idf_target }}_${{ matrix.idf_ver }}.xml
path: components/mdns/${{ matrix.test.path }}/*.xml

61
.github/workflows/mdns__host-tests.yml vendored Normal file
View File

@ -0,0 +1,61 @@
name: "mdns: host-tests"
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened, labeled]
jobs:
host_test_mdns:
if: contains(github.event.pull_request.labels.*.name, 'mdns') || github.event_name == 'push'
name: Host test
runs-on: ubuntu-20.04
container: espressif/idf:latest
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 dnsutils gcc g++
. ${IDF_PATH}/export.sh
cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/tests/host_test
idf.py build
./build/mdns_host.elf &
dig +short -p 5353 @224.0.0.251 myesp.local > ip.txt
cat ip.txt | xargs dig +short -p 5353 @224.0.0.251 -x
cat ip.txt
build_afl_host_test_mdns:
if: contains(github.event.pull_request.labels.*.name, 'mdns') || github.event_name == 'push'
name: Build AFL host test
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

@ -0,0 +1,177 @@
name: "esp-modem: build/host-tests"
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened, labeled]
jobs:
build_esp_modem:
if: contains(github.event.pull_request.labels.*.name, 'modem') || github.event_name == 'push'
name: Build
strategy:
matrix:
idf_ver: ["latest", "release-v4.2", "release-v4.3", "release-v4.4", "release-v5.0"]
example: ["pppos_client", "modem_console", "modem_tcp_client", "ap_to_pppos", "simple_cmux_client"]
exclude:
- idf_ver: "release-v4.2"
example: simple_cmux_client
- idf_ver: "release-v4.2"
example: modem_tcp_client
- idf_ver: "release-v4.3"
example: modem_tcp_client
include:
- idf_ver: "release-v4.2"
skip_config: usb
- idf_ver: "release-v4.3"
skip_config: usb
- idf_ver: "release-v5.0"
example: "simple_cmux_client"
warning: "Warning: The smallest app partition is nearly full"
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
path: protocols
- if: ${{ matrix.skip_config }}
run: rm -f $GITHUB_WORKSPACE/protocols/components/esp_modem/examples/${{ matrix.example }}/sdkconfig.ci.${{ matrix.skip_config }}*
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }}
env:
EXPECTED_WARNING: ${{ matrix.warning }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
python -m pip install idf-build-apps
cd $GITHUB_WORKSPACE/protocols
python ./ci/build_apps.py components/esp_modem/examples/${{ matrix.example }} -m components/esp_modem/examples/.build-test-rules.yml
host_test_esp_modem:
if: contains(github.event.pull_request.labels.*.name, 'modem') || github.event_name == 'push'
name: Host Tests
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
COMP_DIR: esp-protocols/components/esp_modem
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 }}
. ${IDF_PATH}/export.sh
$GITHUB_WORKSPACE/${{ env.COMP_DIR }}/test/host_test/env.sh $lwip $lwip_uri $lwip_contrib
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
host_test_gcov_esp_modem:
if: contains(github.event.pull_request.labels.*.name, 'modem') || github.event_name == 'push'
name: Run gcovr on esp modem host test
runs-on: ubuntu-22.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
COMP_DIR: esp-protocols/components/esp_modem
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
path: esp-protocols
persist-credentials: false
- name: Build and Test
shell: bash
run: |
apt-get update
apt-get update && apt-get install -y gcc-8 g++-8 python3-pip
apt-get install -y rsync
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8
export DEBIAN_FRONTEND=noninteractive
export LWIP_PATH=`pwd`/${{ env.lwip }}
export LWIP_CONTRIB_PATH=`pwd`/${{ env.lwip_contrib }}
. ${IDF_PATH}/export.sh
${{ env.COMP_DIR }}/test/host_test/env.sh $lwip $lwip_uri $lwip_contrib
cd $GITHUB_WORKSPACE/${{ env.COMP_DIR }}/test/host_test
cat sdkconfig.ci.coverage >> sdkconfig.defaults
idf.py build
./build/host_modem_test.elf
- name: Run gcovr
shell: bash
run: |
python -m pip install gcovr
cd $GITHUB_WORKSPACE/${{ env.COMP_DIR }}
gcov-8 `find . -name "esp_modem*gcda" -printf '%h\n' | head -n 1`/*
gcovr --gcov-ignore-parse-errors -g -k -r . --html index.html -x esp_modem_coverage.xml
mkdir docs_gcovr
cp $GITHUB_WORKSPACE/${{ env.COMP_DIR }}/index.html docs_gcovr
touch docs_gcovr/.nojekyll
- name: Code Coverage Summary Report
uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: esp-protocols/**/esp_modem_coverage.xml
badge: true
fail_below_min: false
format: markdown
hide_branch_rate: false
hide_complexity: false
indicators: true
output: both
thresholds: '60 80'
- name: Write to Job Summary
run: cat code-coverage-results.md >> $GITHUB_STEP_SUMMARY
- name: Upload artifacts
uses: actions/upload-artifact@v3
if: always()
with:
name: docs_gcovr
path: |
${{ env.COMP_DIR }}/docs_gcovr
if-no-files-found: error
# show_report_data:
# name: Publish-Results
# if: github.ref == 'refs/heads/master' || github.repository != 'espressif/esp-protocols'
# runs-on: ubuntu-22.04
# needs: gcovr_analyzer_esp_modem
# steps:
# - name: Checkout 🛎️
# uses: actions/checkout@v3
# with:
# persist-credentials: false
# - name: Download Artifacts
# uses: actions/download-artifact@v1
# with:
# name: docs_gcovr
#
# - name: Deploy generated docs
# uses: JamesIves/github-pages-deploy-action@v4
# with:
# branch: gh-pages
# folder: 'docs_gcovr'

View File

@ -0,0 +1,75 @@
name: "esp-modem: target-tests"
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened, labeled]
jobs:
build_esp_modem_tests:
if: contains(github.event.pull_request.labels.*.name, 'modem') || github.event_name == 'push'
name: Build Target tests
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32c3"]
test: [ { app: pppd, path: test/target }, { app: sim800_c3, path: examples/pppos_client } ]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
env:
TEST_DIR: components/esp_modem/${{ matrix.test.path }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build esp-modem target tests with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
SDKCONFIG: sdkconfig.ci.${{ matrix.test.app }}
shell: bash
working-directory: ${{ env.TEST_DIR }}
run: |
. ${IDF_PATH}/export.sh
rm -rf sdkconfig build
[ -f ${SDKCONFIG} ] && cp ${SDKCONFIG} sdkconfig.defaults
idf.py set-target ${{ matrix.idf_target }}
idf.py build
$GITHUB_WORKSPACE/ci/clean_build_artifacts.sh ${GITHUB_WORKSPACE}/${TEST_DIR}/build
- uses: actions/upload-artifact@v3
with:
name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
path: ${{ env.TEST_DIR }}/build
if-no-files-found: error
target_tests_esp_modem:
# Skip running on forks since it won't have access to secrets
if: |
github.repository == 'espressif/esp-protocols' &&
( contains(github.event.pull_request.labels.*.name, 'modem') || github.event_name == 'push' )
name: Run Target tests
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32c3"]
test: [ { app: pppd, path: test/target }, { app: sim800_c3, path: examples/pppos_client } ]
needs: build_esp_modem_tests
runs-on:
- self-hosted
- BrnoRPI-GH006
env:
TEST_DIR: components/esp_modem/${{ matrix.test.path }}
steps:
- name: Clear repository
run: sudo rm -fr $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
path: ${{ env.TEST_DIR }}/build
- name: Run Example Test on target
working-directory: ${{ env.TEST_DIR }}
run: |
python -m pytest --log-cli-level DEBUG --target=${{ matrix.idf_target }}

32
.github/workflows/mqtt_cxx__build.yml vendored Normal file
View File

@ -0,0 +1,32 @@
name: "mqtt-cxx: build-tests"
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened, labeled]
jobs:
build_esp_mqtt_cxx:
if: contains(github.event.pull_request.labels.*.name, 'mqtt') || github.event_name == 'push'
name: Build
strategy:
matrix:
idf_ver: ["latest", "release-v5.0"]
idf_target: ["esp32"]
test: [ { app: example, path: "components/esp_mqtt_cxx/examples" }]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build ${{ matrix.test.app }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
shell: bash
working-directory: ${{matrix.test.path}}
run: |
${IDF_PATH}/install.sh --enable-pytest
. ${IDF_PATH}/export.sh
python $IDF_PATH/tools/ci/ci_build_apps.py . --target ${{ matrix.idf_target }} -vv --preserve-all --pytest-app

View File

@ -12,12 +12,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
ref: ${{ github.base_ref }}
fetch-depth: 20
- name: Fetch head and base refs
# This is necessary for pre-commit to check the changes in the PR branch
# This is necessary for pre-commit to check the changes in the PR branch (and to set origin/HEAD and HEAD refs)
run: |
git fetch origin ${{ github.base_ref }}:base_ref
git fetch origin pull/${{ github.event.pull_request.number }}/head:pr_ref
git fetch origin ${{ github.event.pull_request.head.sha }}:pr_ref
git checkout pr_ref
git remote set-head origin --auto
git merge-base origin/HEAD HEAD || ( echo "Your PR is far behind origin/HEAD, please rebase" && exit 1 )
- name: Set up Python environment
uses: actions/setup-python@master
with:
@ -29,9 +34,9 @@ jobs:
- name: Run pre-commit and check for any changes
run: |
echo "Commits being checked:"
git log --oneline --no-decorate base_ref..pr_ref
git log --oneline --no-decorate origin/HEAD..HEAD
echo ""
if ! pre-commit run --from-ref base_ref --to-ref pr_ref --show-diff-on-failure ; then
if ! pre-commit run --from-ref origin/HEAD --to-ref HEAD --hook-stage manual --show-diff-on-failure ; then
echo ""
echo "::notice::It looks like the commits in this PR have been made without having pre-commit hooks installed."
echo "::notice::Please see https://github.com/espressif/esp-protocols/CONTRIBUTING.md for instructions."

View File

@ -5,66 +5,65 @@ on:
branches:
- master
env:
DOCS_DEPLOY_URL_BASE: ${{ secrets.DOCS_DEPLOY_URL_BASE }}
DOCS_DEPLOY_SERVER: ${{ secrets.DOCS_DEPLOY_SERVER }}
DOCS_DEPLOY_SERVER_USER: ${{ secrets.DOCS_DEPLOY_SERVER_USER }}
DOCS_DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_PRIVATEKEY }}
DOCS_DEPLOY_PATH : ${{ secrets.DOCS_DEPLOY_PATH }}
jobs:
docs_build:
name: Docs-Build-And-Upload
publish:
name: Publish Tag, Release, Docs, Component
runs-on: ubuntu-latest
# Skip running on forks since it won't have access to secrets
if: github.repository == 'espressif/esp-protocols'
steps:
- name: Checkout esp-protocols
uses: actions/checkout@master
uses: actions/checkout@v3
with:
persist-credentials: false
fetch-depth: 0
submodules: recursive
- 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/components/asio/docs
./generate_docs
mkdir -p $GITHUB_WORKSPACE/docs/asio
cp -r html/. $GITHUB_WORKSPACE/docs/asio
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="asio/index.html">ASIO</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
token: "${{ secrets.GITHUB_TOKEN }}"
- name: Check for version update
shell: bash
run: ./ci/detect_component_bump
- name: Tag merge commit
if: env.BUMP_VERSION != ''
uses: anothrNick/github-tag-action@1.61.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CUSTOM_TAG: ${{ env.BUMP_TAG }}
- name: Create Release
if: env.BUMP_VERSION != ''
uses: softprops/action-gh-release@v1
with:
directories: "components/esp_modem;components/esp_websocket_client;components/mdns;components/asio"
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
body_path: "release_notes.md"
tag_name: ${{ env.BUMP_TAG }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: Generate docs
# shell: bash
# run: |
# sudo apt-get update
# sudo apt-get -y install doxygen clang python3-pip
# python -m pip install breathe recommonmark esp-docs==1.4.1
# cd $GITHUB_WORKSPACE/docs
# ./generate_docs
# - name: Deploying generated docs
# if: always()
# shell: bash
# run: |
# source $GITHUB_WORKSPACE/docs/utils.sh
# add_doc_server_ssh_keys $DOCS_DEPLOY_KEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER
# export GIT_VER=$(git describe --always)
# export GITHUB_REF_NAME=latest
# export DOCS_BUILD_DIR=$GITHUB_WORKSPACE/docs
# deploy-docs
# - name: Upload components to component service
# uses: espressif/github-actions/upload_components@master
# with:
# directories: "components/esp_modem;components/esp_websocket_client;components/mdns;components/asio;components/esp_mqtt_cxx"
# namespace: "espressif"
# api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}

View File

@ -1,383 +0,0 @@
name: Build and Run Target tests
on: [push, pull_request]
jobs:
build_esp_modem:
strategy:
matrix:
idf_ver: ["latest", "release-v4.1", "release-v4.2", "release-v4.3", "release-v4.4", "release-v5.0"]
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
build_esp_modem_usb:
strategy:
matrix:
idf_ver: ["latest", "release-v4.4", "release-v5.0"]
example: ["modem_console", "pppos_client"]
idf_target: ["esp32s2", "esp32s3"]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
working-directory: components/esp_modem/examples/${{ matrix.example }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
cat sdkconfig.ci.usb >> sdkconfig.defaults
idf.py build
build_mdns:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32", "esp32s2", "esp32c3"]
test: [ { app: example, path: "components/mdns/examples" }, { app: unit_test, path: "components/mdns/tests/unit_test" } ]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build ${{ matrix.test.app }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
shell: bash
working-directory: ${{ matrix.test.path }}
run: |
${IDF_PATH}/install.sh --enable-pytest
. ${IDF_PATH}/export.sh
python $IDF_PATH/tools/ci/ci_build_apps.py . --target ${{ matrix.idf_target }} -vv --preserve-all --pytest-app
for dir in `ls -d build_*`; do
$GITHUB_WORKSPACE/ci/clean_build_artifacts.sh `pwd`/$dir
zip -qur artifacts.zip $dir
done
- uses: actions/upload-artifact@v3
if: ${{ matrix.idf_target }} == "esp32"
with:
name: mdns_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
path: ${{ matrix.test.path }}/artifacts.zip
if-no-files-found: error
build_asio:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32", "esp32s2"]
example: ["asio_chat", "async_request", "socks4", "ssl_client_server", "tcp_echo_server", "udp_echo_server"]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
env:
TEST_DIR: components/asio/examples
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
working-directory: ${{ env.TEST_DIR }}/${{ matrix.example }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
test -f sdkconfig.ci && cat sdkconfig.ci >> sdkconfig.defaults || echo "No sdkconfig.ci"
idf.py set-target ${{ matrix.idf_target }}
idf.py build
- name: Merge binaries with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }} for ${{ matrix.example }}
working-directory: ${{ env.TEST_DIR }}/${{ matrix.example }}/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@v3
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.example }}
path: |
${{ env.TEST_DIR }}/${{ matrix.example }}/build/bootloader/bootloader.bin
${{ env.TEST_DIR }}/${{ matrix.example }}/build//partition_table/partition-table.bin
${{ env.TEST_DIR }}/${{ matrix.example }}/build/*.bin
${{ env.TEST_DIR }}/${{ matrix.example }}/build/*.elf
${{ env.TEST_DIR }}/${{ matrix.example }}/build/flasher_args.json
${{ env.TEST_DIR }}/${{ matrix.example }}/build/config/sdkconfig.h
${{ env.TEST_DIR }}/${{ matrix.example }}/build/config/sdkconfig.json
if-no-files-found: error
build_websocket:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32"]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
env:
TEST_DIR: components/esp_websocket_client/examples
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
working-directory: ${{ env.TEST_DIR }}
run: |
. ${IDF_PATH}/export.sh
cat sdkconfig.ci >> sdkconfig.defaults
idf.py build
- name: Merge binaries
working-directory: ${{ env.TEST_DIR }}/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@v3
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: |
${{ env.TEST_DIR }}/build/bootloader/bootloader.bin
${{ env.TEST_DIR }}/build/partition_table/partition-table.bin
${{ env.TEST_DIR }}/build/*.bin
${{ env.TEST_DIR }}/build/*.elf
${{ env.TEST_DIR }}/build/flasher_args.json
${{ env.TEST_DIR }}/build/config/sdkconfig.h
${{ env.TEST_DIR }}/build/config/sdkconfig.json
if-no-files-found: error
build_esp_mqtt_cxx:
strategy:
matrix:
idf_ver: ["latest", "release-v5.0"]
idf_target: ["esp32"]
test: [ { app: example, path: "components/esp_mqtt_cxx/examples" }]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build ${{ matrix.test.app }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
shell: bash
working-directory: ${{matrix.test.path}}
run: |
${IDF_PATH}/install.sh --enable-pytest
. ${IDF_PATH}/export.sh
python $IDF_PATH/tools/ci/ci_build_apps.py . --target ${{ matrix.idf_target }} -vv --preserve-all --pytest-app
run-target-websocket:
name: Run Websocket Example Test on target
needs: build_websocket
strategy:
fail-fast: false
matrix:
idf_ver: ["latest"]
idf_target: ["esp32"]
runs-on:
- self-hosted
- ESP32-ETHERNET-KIT
env:
TEST_DIR: components/esp_websocket_client/examples
# Skip running on forks since it won't have access to secrets
if: github.repository == 'espressif/esp-protocols'
steps:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: ${{ env.TEST_DIR }}/build/
- name: Install Python packages
env:
PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple"
run: |
pip install --only-binary cryptography --extra-index-url https://dl.espressif.com/pypi/ -r $GITHUB_WORKSPACE/ci/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: ${{ env.TEST_DIR }}
run: |
python -m pytest --log-cli-level DEBUG --junit-xml=./examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}.xml --target=${{ matrix.idf_target }}
- uses: actions/upload-artifact@v3
if: always()
with:
name: examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: ${{ env.TEST_DIR }}/*.xml
run-target-mdns:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32"]
test: [ { app: example, path: "components/mdns/examples" }, { app: unit_test, path: "components/mdns/tests/unit_test" } ]
name: Run mDNS target tests
needs: build_mdns
runs-on:
- self-hosted
- ESP32-ETHERNET-KIT
# Skip running on forks since it won't have access to secrets
if: github.repository == 'espressif/esp-protocols'
steps:
- name: Clear repository
run: sudo rm -fr $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: mdns_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
path: ${{ matrix.test.path }}/ci/
- name: Install Python packages
env:
PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple"
run: |
sudo apt-get install -y dnsutils
- name: Run ${{ matrix.test.app }} application on ${{ matrix.idf_target }}
working-directory: ${{ matrix.test.path }}
run: |
unzip ci/artifacts.zip -d ci
for dir in `ls -d ci/build_*`; do
rm -rf build sdkconfig.defaults
mv $dir build
python -m pytest --log-cli-level DEBUG --junit-xml=./results_${{ matrix.test.app }}_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${dir#"ci/build_"}.xml --target=${{ matrix.idf_target }}
done
- uses: actions/upload-artifact@v3
if: always()
with:
name: results_${{ matrix.test.app }}_${{ matrix.idf_target }}_${{ matrix.idf_ver }}.xml
path: ${{ matrix.test.path }}/*.xml
run-target-asio:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32"]
example: ["asio_chat", "tcp_echo_server", "udp_echo_server", "ssl_client_server"]
name: Run ASIO Example Test on target
needs: build_asio
runs-on:
- self-hosted
- ESP32-ETHERNET-KIT
env:
TEST_DIR: components/asio/examples
# Skip running on forks since it won't have access to secrets
if: github.repository == 'espressif/esp-protocols'
steps:
- name: Clear repository
run: sudo rm -fr $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.example }}
path: ${{ env.TEST_DIR }}/${{ matrix.example }}/build
- name: Install Python packages
env:
PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple"
run: |
sudo apt-get install -y dnsutils
- name: Download Example Test to target ${{ matrix.config }}
run: |
python -m esptool --chip ${{ matrix.idf_target }} write_flash 0x0 ${{ env.TEST_DIR }}/${{ matrix.example }}/build/flash_image.bin
- name: Run Example Test ${{ matrix.example }} on target
working-directory: ${{ env.TEST_DIR }}/${{ matrix.example }}
run: |
python -m pytest --log-cli-level DEBUG --junit-xml=./examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.config }}.xml --target=${{ matrix.idf_target }}
- uses: actions/upload-artifact@v3
if: always()
with:
name: examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.example }}
path: ${{ env.TEST_DIR }}/${{ matrix.example }}/*.xml
build_esp_modem_tests:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32c3"]
test: [ { app: pppd, path: test/target }, { app: sim800, path: examples/pppos_client } ]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
env:
TEST_DIR: components/esp_modem/${{ matrix.test.path }}
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build esp-modem target tests with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
SDKCONFIG: sdkconfig.ci.${{ matrix.test.app }}
shell: bash
working-directory: ${{ env.TEST_DIR }}
run: |
. ${IDF_PATH}/export.sh
rm -rf sdkconfig build
[ -f ${SDKCONFIG} ] && cp ${SDKCONFIG} sdkconfig.defaults
idf.py set-target ${{ matrix.idf_target }}
idf.py build
$GITHUB_WORKSPACE/ci/clean_build_artifacts.sh ${GITHUB_WORKSPACE}/${TEST_DIR}/build
- uses: actions/upload-artifact@v3
with:
name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
path: ${{ env.TEST_DIR }}/build
if-no-files-found: error
run_esp_modem_tests:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32c3"]
test: [ { app: pppd, path: test/target }, { app: sim800, path: examples/pppos_client } ]
name: Run esp_modem Test on target
needs: build_esp_modem_tests
runs-on:
- self-hosted
- BrnoRPI-GH006
env:
TEST_DIR: components/esp_modem/${{ matrix.test.path }}
# Skip running on forks since it won't have access to secrets
if: github.repository == 'espressif/esp-protocols'
steps:
- name: Clear repository
run: sudo rm -fr $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
path: ${{ env.TEST_DIR }}/build
- name: Run Example Test on target
working-directory: ${{ env.TEST_DIR }}
run: |
python -m pytest --log-cli-level DEBUG --target=${{ matrix.idf_target }}

View File

@ -1,30 +0,0 @@
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,94 +0,0 @@
name: Build and Run Test apps
on:
push:
paths:
- 'components/mdns/**'
pull_request:
paths:
- 'components/mdns/**'
jobs:
build_mdns_app:
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@v3
with:
submodules: recursive
- name: Setup Build Environment
working-directory: components/mdns/tests/test_apps
run: |
. ${IDF_PATH}/export.sh
pip install -r $GITHUB_WORKSPACE/ci/requirements.txt
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
working-directory: components/mdns/tests/test_apps
run: |
. ${IDF_PATH}/export.sh
python $IDF_PATH/tools/ci/ci_build_apps.py . --target ${{ matrix.idf_target }} -vv --pytest-apps
- name: Merge binaries with IDF-${{ matrix.idf_ver }}
working-directory: components/mdns/tests/test_apps/build_${{ matrix.idf_target }}_default
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/mdns/tests/test_apps/build_${{ matrix.idf_target }}_default/bootloader/bootloader.bin
components/mdns/tests/test_apps/build_${{ matrix.idf_target }}_default/partition_table/partition-table.bin
components/mdns/tests/test_apps/build_${{ matrix.idf_target }}_default/*.bin
components/mdns/tests/test_apps/build_${{ matrix.idf_target }}_default/*.elf
components/mdns/tests/test_apps/build_${{ matrix.idf_target }}_default/flasher_args.json
components/mdns/tests/test_apps/build_${{ matrix.idf_target }}_default/config/sdkconfig.h
components/mdns/tests/test_apps/build_${{ matrix.idf_target }}_default/config/sdkconfig.json
if-no-files-found: error
run-target-mdns-app:
strategy:
matrix:
idf_ver: ["latest"]
idf_target: ["esp32"]
name: Run mDNS Test apps on target
needs: build_mdns_app
runs-on:
- self-hosted
- ESP32-ETHERNET-KIT
# Skip running on forks since it won't have access to secrets
if: github.repository == 'espressif/esp-protocols'
steps:
- name: Clear repository
run: sudo rm -fr $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE
- uses: actions/checkout@v3
- uses: actions/download-artifact@v2
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: components/mdns/tests/test_apps/build
- name: Install Python packages
env:
PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple"
run: |
sudo apt-get install -y dnsutils
- name: Download Test apps to target
run: |
python -m esptool --chip ${{ matrix.idf_target }} write_flash 0x0 components/mdns/tests/test_apps/build/flash_image.bin
- name: Run Example Test on target
working-directory: components/mdns/tests/test_apps
run: |
python -m pytest --log-cli-level DEBUG --junit-xml=./examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}.xml --target=${{matrix.idf_target}}
- uses: actions/upload-artifact@v2
if: always()
with:
name: test_apps_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: components/mdns/tests/test_apps/*.xml

View File

@ -0,0 +1,95 @@
name: "websocket: build/target-tests"
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened, labeled]
jobs:
build_websocket:
if: contains(github.event.pull_request.labels.*.name, 'websocket') || github.event_name == 'push'
name: Build
strategy:
matrix:
idf_ver: ["release-v5.0", "latest"]
idf_target: ["esp32"]
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
env:
TEST_DIR: components/esp_websocket_client/examples
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
working-directory: ${{ env.TEST_DIR }}
run: |
. ${IDF_PATH}/export.sh
cat sdkconfig.ci >> sdkconfig.defaults
idf.py build
- name: Merge binaries
working-directory: ${{ env.TEST_DIR }}/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@v3
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: |
${{ env.TEST_DIR }}/build/bootloader/bootloader.bin
${{ env.TEST_DIR }}/build/partition_table/partition-table.bin
${{ env.TEST_DIR }}/build/*.bin
${{ env.TEST_DIR }}/build/*.elf
${{ env.TEST_DIR }}/build/flasher_args.json
${{ env.TEST_DIR }}/build/config/sdkconfig.h
${{ env.TEST_DIR }}/build/config/sdkconfig.json
if-no-files-found: error
run-target-websocket:
# Skip running on forks since it won't have access to secrets
if: |
github.repository == 'espressif/esp-protocols' &&
( contains(github.event.pull_request.labels.*.name, 'websocket') || github.event_name == 'push' )
name: Target test
needs: build_websocket
strategy:
fail-fast: false
matrix:
idf_ver: ["release-v5.0", "latest"]
idf_target: ["esp32"]
runs-on:
- self-hosted
- ESP32-ETHERNET-KIT
env:
TEST_DIR: components/esp_websocket_client/examples
steps:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: ${{ env.TEST_DIR }}/build/
- name: Install Python packages
env:
PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple"
run: |
pip install --only-binary cryptography --extra-index-url https://dl.espressif.com/pypi/ -r $GITHUB_WORKSPACE/ci/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: ${{ env.TEST_DIR }}
run: |
python -m pytest --log-cli-level DEBUG --junit-xml=./examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}.xml --target=${{ matrix.idf_target }}
- uses: actions/upload-artifact@v3
if: always()
with:
name: examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
path: ${{ env.TEST_DIR }}/*.xml

View File

@ -16,6 +16,7 @@ repos:
rev: 5.0.4
hooks:
- id: flake8
args: ['--config=.flake8', '--tee', '--benchmark']
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.981
hooks:
@ -32,6 +33,7 @@ repos:
rev: "v0.32.0"
hooks:
- id: yapf
args: ['style={based_on_style: google, column_limit: 160, indent_width: 4}']
- repo: https://github.com/pre-commit/mirrors-isort
rev: v5.10.1
hooks:
@ -50,3 +52,17 @@ repos:
hooks:
- id: astyle_py
args: ['--style=otbs', '--attach-namespaces', '--attach-classes', '--indent=spaces=4', '--convert-tabs', '--align-pointer=name', '--align-reference=name', '--keep-one-line-statements', '--pad-header', '--pad-oper']
- repo: https://github.com/commitizen-tools/commitizen
rev: v2.42.1
hooks:
- id: commitizen
- id: commitizen-branch
stages: [push, manual]
- repo: local
hooks:
- id: commit message scopes
name: "commit message must be scoped with: mdns, modem, websocket, asio, mqtt_cxx, common"
entry: '\A(?!(feat|fix|ci|bump|test|docs)\((mdns|modem|common|websocket|asio|mqtt_cxx)\)\:)'
language: pygrep
args: [--multiline]
stages: [commit-msg]

View File

@ -6,8 +6,26 @@ Contributions in the form of pull requests, issue reports, and feature requests
- [ ] Fork the [esp-protocols repository on GitHub](https://github.com/espressif/esp-protocols) to start making your changes.
- [ ] Install pre-commit hooks: `pip install pre-commit && pre-commit install`
- [ ] Install pre-commit hooks: `pip install pre-commit && pre-commit install-hooks && pre-commit install --hook-type commit-msg --hook-type pre-push`
- [ ] Send a pull request (PR) and work with us until it gets merged and published. Contributions may need some modifications, so a few rounds of review and fixing may be necessary.
For quick merging, the contribution should be short, and concentrated on a single feature or topic. The larger the contribution is, the longer it would take to review it and merge it.
Please follow the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) rule when writing commit messages.
## Release process
When releasing a new component version we have to:
* Update the version number
* Update the changelog
* Create the version tag in this repository
* Deploy the component to component registry
* Update the documentation
This process is not fully automated, the first step needs to be performed manually by project maintainers running the `bump` command. Release procedure is as follows:
* Run `ci/bump [component] [version]` (version number is optional, `cz` would automatically increment it if not present)
* Check the updated `CHANGELOG.md` and the generated bump commit message
* Create a PR
Once the PR is merged, the CI job tags the merge commit, creates a new release, builds and deploys documentation and the new component to the component registry

View File

@ -1,26 +1,29 @@
# 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)
* Full html [documentation](https://docs.espressif.com/projects/esp-protocols/esp_modem/docs/latest/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)
* Full html [documentation(English)](https://docs.espressif.com/projects/esp-protocols/mdns/docs/latest/en/index.html)
* Full html [documentation(Chinese)](https://docs.espressif.com/projects/esp-protocols/mdns/docs/latest/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)
* Full html [documentation](https://docs.espressif.com/projects/esp-protocols/esp_websocket_client/docs/latest/index.html)
### ASIO port
* Brief introduction [README](components/asio/README.md)
* Full html [documentation](https://espressif.github.io/esp-protocols/asio/index.html)
* Full html [documentation](https://docs.espressif.com/projects/esp-protocols/asio/docs/latest/index.html)
### esp_mqtt_cxx
* Brief introduction [README](components/esp_mqtt_cxx/README.md)
* Full html [documentation](https://docs.espressif.com/projects/esp-protocols/esp_mqtt_cxx/docs/latest/index.html)

58
ci/build_apps.py Normal file
View File

@ -0,0 +1,58 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
"""
This file is used in CI for esp-protocols build tests
"""
import argparse
import os
import sys
from idf_build_apps import build_apps, find_apps, setup_logging
from idf_build_apps.constants import SUPPORTED_TARGETS
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Build all projects',
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument('paths', nargs='+', help='Paths to the apps to build.')
parser.add_argument(
'-t',
'--target',
default='all',
help='Build apps for given target',
)
parser.add_argument('-r', '--rules', nargs='*', default=['sdkconfig.ci=default', 'sdkconfig.ci.*=', '=default'], help='Rules how to treat configs')
parser.add_argument('-m', '--manifests', nargs='*', default=[], help='list of manifest files')
parser.add_argument('-d', '--delete', action='store_true', help='Delete build artifacts')
args = parser.parse_args()
IDF_PATH = os.environ['IDF_PATH']
print(args.paths)
setup_logging(2)
apps = find_apps(
args.paths,
recursive=False,
target=args.target,
build_dir='build_@t_@w',
config_rules_str=args.rules,
build_log_path='build_log.txt',
size_json_path='size.json',
check_warnings=True,
preserve=not args.delete,
manifest_files=args.manifests,
default_build_targets=SUPPORTED_TARGETS,
manifest_rootpath='.',
)
for app in apps:
print(app)
sys.exit(
build_apps(apps,
dry_run=False,
keep_going=False,
ignore_warning_strs=os.environ['EXPECTED_WARNING']
if 'EXPECTED_WARNING' in os.environ else None))

23
ci/bump Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env bash
if [ -z "$1" ]; then
echo "Usage: bump component [version]"
exit 1;
fi
comp=$1; shift;
cd components/${comp}
if ! cz bump --dry-run; then
echo "Commitizen bump commad failed!"
exit 1;
fi
cz_bump_out=`cz bump --files-only "$@"`
commit_title=`echo "${cz_bump_out}" | head -1`
commit_body=`cat ../../release_notes.txt`
git add -u .
git commit -m $"${commit_title}
${commit_body}"

105
ci/changelog.py Normal file
View File

@ -0,0 +1,105 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import argparse
import os
import re
import sh
def main():
parser = argparse.ArgumentParser(
description='Generates a change log from cz commits')
parser.add_argument('component')
args = parser.parse_args()
old_ref = os.environ.get('CZ_PRE_CURRENT_TAG_VERSION')
new_tag = os.environ.get('CZ_PRE_NEW_TAG_VERSION')
new_ref = os.environ.get('CZ_PRE_NEW_VERSION')
component = args.component
root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
git = sh.git.bake(_cwd=root_path)
keys = ['breaking', 'major', 'feat', 'fix', 'update']
items = {key: [] for key in keys}
sections = {
'feat': 'Features',
'fix': 'Bug Fixes',
'update': 'Updated',
'breaking': 'Breaking changes',
'major': 'Major changes'
}
brief_log = git.log('--oneline', '{}..HEAD'.format(old_ref), '--', 'components/' + component, _tty_out=False)
for oneline in brief_log.splitlines():
[commit, brief_msg] = oneline.split(' ', 1)
if 'Merge' in str(brief_msg) or brief_msg.startswith('bump('): # skip Merge commits and bumps
continue
find_title = re.findall(r'^(fix|feat|esp_modem|esp-modem|mdns)(\([^\)]+\))?:\s*(.+)$', str(brief_msg))
item_type = '' # default prefix
item_message = brief_msg # default body
if find_title is not None and len(find_title) > 0: # Use scopes & types
item_type = find_title[0][0] # prefix (fix/feat/ci)
item_message = find_title[0][-1] # title body
# Add details in parentheses (commit-id and references from the FOOTER section)
details = '[{}](https://github.com/espressif/esp-protocols/commit/{})'.format(commit, commit)
msg_details = git.show('-s', commit, _tty_out=False)
# check references
if any(s in str(msg_details) for s in ['esp-protocols/issues', 'BREAKING CHANGE', 'MAJOR CHANGE']):
# Closes <issue>
closes = re.findall(r'Closes ([^\d]+/(\d+))', str(msg_details), re.MULTILINE)
if closes and closes[0] is not None:
details += ', [#{}]({})'.format(closes[0][1], closes[0][0])
# Breaking changes
find_breaking = re.findall(r'BREAKING CHANGE:\s*([^\n]*)', str(msg_details), re.MULTILINE)
if find_breaking is not None and len(find_breaking) > 0:
if find_breaking[0] != '':
items['breaking'].append('{} ([{}](https://github.com/espressif/esp-protocols/commit/{}))'.format(find_breaking[0], item_message, commit))
else:
items['breaking'].append('{} ({})'.format(item_message, details))
details += ', !BREAKING'
# Major changes
find_major = re.findall(r'MAJOR CHANGE:\s*([^\n]*)',
str(msg_details), re.MULTILINE)
if find_major is not None and len(
find_major) > 0 and find_major[0] != '':
items['major'].append('{} ([{}](https://github.com/espressif/esp-protocols/commit/{}))'.format(find_major[0], item_message, commit))
if item_type in ['fix', 'feat']:
items[item_type].append('{} ({})'.format(item_message, details))
else:
items['update'].append('{} ({})'.format(item_message, details))
# Generate changelog
changelog = '## [{}](https://github.com/espressif/esp-protocols/commits/{})\n'.format(
new_ref, new_tag)
for section, item in items.items():
if len(item) > 0:
changelog += '\n### {}\n\n'.format(sections[section])
for it in item:
changelog += '- {}\n'.format(it)
changelog += '\n'
filename = os.path.join(root_path, 'components', component, 'CHANGELOG.md')
# insert the actual changelog to the beginning of the file, just after the title (2nd line)
with open(filename, 'r') as orig_changelog:
changelog_title = orig_changelog.readline(
) # expect # Changelog title on the first line
changelog_nl = orig_changelog.readline()
orig_items = orig_changelog.read()
with open(filename, 'w') as updated_changelog:
updated_changelog.write(changelog_title)
updated_changelog.write(changelog_nl)
updated_changelog.write(changelog)
updated_changelog.write(orig_items)
git.add(filename)
# write the current changelog entry to a local text file (removing links, captions and extra newlines)
changelog = re.sub(r'\[([^\]]+)\]\([^\)]+\)', r'\1', changelog)
changelog = re.sub(r'\#\#[\#\s]*(.+)', r'\1', changelog)
changelog = re.sub(r'\n\n', '\n', changelog)
with open(os.path.join(root_path, 'release_notes.txt'), 'w') as release_notes:
release_notes.write(changelog)
if __name__ == '__main__':
main()

View File

@ -57,7 +57,7 @@ slim_modem_examples:
ignore:
perform_check: no
include:
- 'components/**/docs/**'
- '**/docs/**'
- 'components/esp_modem/port/linux/**'
- 'components/asio/examples/**'
- 'components/mdns/**/esp_system_protocols_linux/**'

36
ci/detect_component_bump Executable file
View File

@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -e
if ! git show -s | grep -q '^Merge'; then
echo "Not a merge commit"
exit 0;
fi
for comp in `ls components`; do
if git log -1 -m --name-only --pretty="" | grep -q components/${comp}/idf_component.yml; then
echo "${comp}: Component version has been updated"
version=`grep version: components/${comp}/.cz.yaml`
version=${version#*version: }
tag_format=`grep tag_format: components/${comp}/.cz.yaml`
tag_format=${tag_format#*tag_format: }
eval tag=$tag_format
# creates release notes from the last entry (between first two "## sections")
awk '/^## \[/{a++};{if(a==1){print}}' components/${comp}/CHANGELOG.md > release_notes.md
echo "BUMP_VERSION=${version}"
echo "BUMP_COMPONENT=${comp}"
echo "BUMP_TAG=${tag}"
# export the findings to github env, so it could be used in other jobs
echo "BUMP_VERSION=${version}" >> "$GITHUB_ENV"
echo "BUMP_COMPONENT=${comp}" >> "$GITHUB_ENV"
echo "BUMP_TAG=${tag}" >> "$GITHUB_ENV"
exit 0;
fi
done
echo "No changes in component version file"

View File

@ -0,0 +1,43 @@
# Changelog
## [1.14.1~3](https://github.com/espressif/esp-protocols/commits/f148c98)
### Updated
- ASIO: Updated package version to "1.14.1~3" ([f148c98](https://github.com/espressif/esp-protocols/commit/f148c98))
- ASIO: Example tests integration ([5193ebc](https://github.com/espressif/esp-protocols/commit/5193ebc))
## [1.0.2](https://github.com/espressif/esp-protocols/commits/57afa38)
### Updated
- Bump asio/mdns/esp_websocket_client versions ([57afa38](https://github.com/espressif/esp-protocols/commit/57afa38))
- ignore format warnings ([d66f9dc](https://github.com/espressif/esp-protocols/commit/d66f9dc))
- asio: Fix exampels build ([3662c14](https://github.com/espressif/esp-protocols/commit/3662c14))
## [1.0.1](https://github.com/espressif/esp-protocols/commits/055f051)
### Updated
- ASIO: Initial version based on IDF 5.0 with history ([055f051](https://github.com/espressif/esp-protocols/commit/055f051))
- asio: Disable concepts support Fix example for compatibility with C++20 ([ac7bf46](https://github.com/espressif/esp-protocols/commit/ac7bf46), [IDF@9dba047](https://github.com/espressif/esp-idf/commit/9dba0476a01cd80d76e21706ad350009606b877e))
- lwip: Update socket API to include port-version of sockets/netdb ([057a5d2](https://github.com/espressif/esp-protocols/commit/057a5d2), [IDF@53c009e](https://github.com/espressif/esp-idf/commit/53c009e62631bae569fa849c6b6c9e70a10b3afe))
- esp_netif/lwip: Implement basic support for vanilla-lwip (2.1.3-REL) ([63bff63](https://github.com/espressif/esp-protocols/commit/63bff63), [IDF@5b471a1](https://github.com/espressif/esp-idf/commit/5b471a18489b056f65fe8dcbb2c992d27909ebc9))
- mbedtls: Remove certs.c and certs.h from port directory ([e3c4391](https://github.com/espressif/esp-protocols/commit/e3c4391), [IDF@f31d8dd](https://github.com/espressif/esp-idf/commit/f31d8dd2955be0fe949340dcf3b043ec6daf4378))
- mbedtls-3 update: 1) Fix build issue in mbedtls 2) skip the public headers check in IDF 3)Update Kconfig Macros 4)Remove deprecated config options 5) Update the sha API according to new nomenclature 6) Update mbedtls_rsa_init usage 7) Include mbedtls/build_info.h instead of mbedtls/config.h 8) Dont include check_config.h 9) Add additional error message in esp_blufi_api.h ([9813818](https://github.com/espressif/esp-protocols/commit/9813818), [IDF@4512253](https://github.com/espressif/esp-idf/commit/45122533e0bca5d538585e22308f14b74c33e474))
- asio: Use internal ssl context and engine impl ([f605fdd](https://github.com/espressif/esp-protocols/commit/f605fdd), [IDF@d823106](https://github.com/espressif/esp-idf/commit/d823106aa6b24b8bdcc30373513c8688c61438c4))
- Build & config: Remove leftover files from the unsupported "make" build system ([abbc8d9](https://github.com/espressif/esp-protocols/commit/abbc8d9), [IDF@766aa57](https://github.com/espressif/esp-idf/commit/766aa5708443099f3f033b739cda0e1de101cca6))
- openssl: Add deprecation warning to ssl.h ([a029774](https://github.com/espressif/esp-protocols/commit/a029774), [IDF@cfc0018](https://github.com/espressif/esp-idf/commit/cfc001870c5e0afed7b42b6bf8c326eae053fe96))
- asio coap: If LWIP IPV6 is disabled, automatically don't build asio & coap ([cc0f2b3](https://github.com/espressif/esp-protocols/commit/cc0f2b3), [IDF@e305f29](https://github.com/espressif/esp-idf/commit/e305f2938278c2a39e75c21a3ed59d8f4d4e62fa))
- asio: update copyright notice ([47d57a5](https://github.com/espressif/esp-protocols/commit/47d57a5), [IDF@2d0895e](https://github.com/espressif/esp-idf/commit/2d0895e9a98bc7846d0ac7321f2b86b47346bf21))
- Whitespace: Automated whitespace fixes (large commit) ([622a360](https://github.com/espressif/esp-protocols/commit/622a360), [IDF@66fb5a2](https://github.com/espressif/esp-idf/commit/66fb5a29bbdc2482d67c52e6f66b303378c9b789))
- cmake: Apply cmakelint fixes ([4358c3c](https://github.com/espressif/esp-protocols/commit/4358c3c), [IDF@e82eac4](https://github.com/espressif/esp-idf/commit/e82eac4354b8b4111697656f3acce7450eeff366))
- asio: option to use wolfSSL as TLS stack for ASIO ([c05558b](https://github.com/espressif/esp-protocols/commit/c05558b), [IDF@1c8171c](https://github.com/espressif/esp-idf/commit/1c8171c3e8d5a67e47dc8d6abac27ad2989470c3))
- asio: Basic SSL/TLS support in asio port for ESP platform ([dab1230](https://github.com/espressif/esp-protocols/commit/dab1230), [IDF@9459c0d](https://github.com/espressif/esp-idf/commit/9459c0dd432fdd0fccb49ea65bb5c72d1849e1ba))
- asio: updated ASIO port to use latest asio and esp-idf features ([9190917](https://github.com/espressif/esp-protocols/commit/9190917), [IDF@13d603e](https://github.com/espressif/esp-idf/commit/13d603e486624380d49f2e89614b10425c208d14))
- components: use new component registration api ([9e83b1e](https://github.com/espressif/esp-protocols/commit/9e83b1e), [IDF@9eccd7c](https://github.com/espressif/esp-idf/commit/9eccd7c0826d6cc2e9de59304d1e5f76c0063ccf))
- Rename Kconfig options (root) ([3b49d1f](https://github.com/espressif/esp-protocols/commit/3b49d1f), [IDF@c5000c8](https://github.com/espressif/esp-idf/commit/c5000c83d250896fffbddd7a3991384ea0fc286d))
- cmake: make main a component again ([57672d5](https://github.com/espressif/esp-protocols/commit/57672d5), [IDF@d9939ce](https://github.com/espressif/esp-idf/commit/d9939cedd9b44d63dc148354c3a0a139b9c7113d))
- asio: initial idf port of asio library without ssl ([5472d5c](https://github.com/espressif/esp-protocols/commit/5472d5c), [IDF@1ef13c5](https://github.com/espressif/esp-idf/commit/1ef13c524c484e9fb62e6c0b11482c30c5383728))

23
components/asio/LICENSE Normal file
View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -6,8 +6,8 @@ Asio is a cross-platform C++ library, see https://think-async.com/Asio/. It prov
## Examples
Get started with example test :example:`examples <examples/..>`:
Get started with examples [examples](https://github.com/espressif/esp-protocols/tree/master/components/asio/examples)
## Documentation
* View the full [html documentation](https://espressif.github.io/esp-protocols/asio/index.html)
* View the full [html documentation](https://docs.espressif.com/projects/esp-protocols/asio/docs/latest/index.html)

View File

@ -1,5 +1,6 @@
version: "1.14.1~3"
description: ASIO
url: https://github.com/espressif/esp-protocols/tree/master/components/asio
dependencies:
idf:
version: ">=5.0"

View File

@ -0,0 +1,8 @@
---
commitizen:
bump_message: 'bump(modem): $current_version -> $new_version'
pre_bump_hooks: python ../../ci/changelog.py esp_modem
tag_format: modem-v$version
version: 1.0.0
version_files:
- idf_component.yml

View File

@ -0,0 +1,337 @@
# Changelog
## [1.0.0](https://github.com/espressif/esp-protocols/commits/modem-v1.0.0)
### Major changes
- Enable DTE to redefine on_read() and write(cmd) directly ([DTE to support sending and receiving raw data](https://github.com/espressif/esp-protocols/commit/bf114d3))
### Features
- Add mqtt example in AT-only mode ([7547267](https://github.com/espressif/esp-protocols/commit/7547267))
- DTE to support sending and receiving raw data ([bf114d3](https://github.com/espressif/esp-protocols/commit/bf114d3))
### Bug Fixes
- Changelog to correctly pick references ([c59e330](https://github.com/espressif/esp-protocols/commit/c59e330))
- AT-only example: support MQTT over TLS on BG96 ([31d4323](https://github.com/espressif/esp-protocols/commit/31d4323))
- AT-only example: initial adaptation to BG96 ([ceedcfc](https://github.com/espressif/esp-protocols/commit/ceedcfc))
- warning in ap-2-pppos example when using lwip/napt ([bf32e45](https://github.com/espressif/esp-protocols/commit/bf32e45))
- trigger PR jobs based on labels ([13eca12](https://github.com/espressif/esp-protocols/commit/13eca12))
- Reintroduce missing CHANGELOGs ([200cbb3](https://github.com/espressif/esp-protocols/commit/200cbb3), [#235](https://github.com/espressif/esp-protocols/issues/235))
- Use default UART CLK source ([d0814bf](https://github.com/espressif/esp-protocols/commit/d0814bf), [#241](https://github.com/espressif/esp-protocols/issues/241))
- run CI build job for all targets ([a089e0d](https://github.com/espressif/esp-protocols/commit/a089e0d))
### Updated
- Update examples for USB v1.1 ([610372f](https://github.com/espressif/esp-protocols/commit/610372f))
## [0.1.28](https://github.com/espressif/esp-protocols/commits/01c26c8)
### Updated
- Dual DTE support ([01c26c8](https://github.com/espressif/esp-protocols/commit/01c26c8))
## [0.1.27](https://github.com/espressif/esp-protocols/commits/44bae24)
### Updated
- Return true from on_data callback in data mode ([44bae24](https://github.com/espressif/esp-protocols/commit/44bae24))
## [0.1.26](https://github.com/espressif/esp-protocols/commits/05fff94)
### Features
- Added target test ([4314c78](https://github.com/espressif/esp-protocols/commit/4314c78))
- Add support for manual CMUX operations ([ac5d438](https://github.com/espressif/esp-protocols/commit/ac5d438), [#168](https://github.com/espressif/esp-protocols/issues/168))
### Bug Fixes
- Example to use variable mqtt topic/data ([8958d5e](https://github.com/espressif/esp-protocols/commit/8958d5e))
- Fix cmux client compilation issue ([f71192b](https://github.com/espressif/esp-protocols/commit/f71192b))
- Exit data mode only after state change ([9a7bd90](https://github.com/espressif/esp-protocols/commit/9a7bd90))
- Support AT with callback in C-API ([2180ab1](https://github.com/espressif/esp-protocols/commit/2180ab1), [#143](https://github.com/espressif/esp-protocols/issues/143))
### Updated
- update(esp_modem): Bump component version to 0.1.26 ([05fff94](https://github.com/espressif/esp-protocols/commit/05fff94), [#213](https://github.com/espressif/esp-protocols/issues/213))
- Added the missing definition for the esp_modem_set_baud function (IDFGH-9181) (#209) ([0e215b1](https://github.com/espressif/esp-protocols/commit/0e215b1))
- CI: Added coverage analyzer for esp_modem host tests ([6b684ce](https://github.com/espressif/esp-protocols/commit/6b684ce))
- Update esp_modem_command_library.cpp ([5304a6e](https://github.com/espressif/esp-protocols/commit/5304a6e))
- Added badges with version of components to the respective README files ([e4c8a59](https://github.com/espressif/esp-protocols/commit/e4c8a59))
- esp_modem/examples: Add an example to synchronise PSM sleep in Sim70XX modem and esp32. ([1ca1391](https://github.com/espressif/esp-protocols/commit/1ca1391))
## [0.1.25](https://github.com/espressif/esp-protocols/commits/f1ae14f)
### Bug Fixes
- Cleanup custom lib-commands and factory ([65c0e0e](https://github.com/espressif/esp-protocols/commit/65c0e0e))
- Examples to configure MQTT Broker ([71a2388](https://github.com/espressif/esp-protocols/commit/71a2388))
- Extend pppos example project config ([ebc36a3](https://github.com/espressif/esp-protocols/commit/ebc36a3))
- Uart Terminal read_cb race ([a02bf05](https://github.com/espressif/esp-protocols/commit/a02bf05))
### Updated
- update(esp_modem): Bump component version ([f1ae14f](https://github.com/espressif/esp-protocols/commit/f1ae14f))
- fix(esp_modem) Add example that reads GNSS info ([652314e](https://github.com/espressif/esp-protocols/commit/652314e))
- CI: fixing the files to be complient with pre-commit hooks ([945bd17](https://github.com/espressif/esp-protocols/commit/945bd17))
- Quick fix esp_modem: Added modem_console commands for deep-sleep and modem PSM. ([cf504ec](https://github.com/espressif/esp-protocols/commit/cf504ec))
- fix(esp-modem) Make simple_cmux_client example configurable ([511ed54](https://github.com/espressif/esp-protocols/commit/511ed54))
- Added modem_console commands for deep-sleep and modem PSM. ([85a2e25](https://github.com/espressif/esp-protocols/commit/85a2e25))
- ci: Compile esp_modem examples with USB support ([988b3f9](https://github.com/espressif/esp-protocols/commit/988b3f9))
- Expand PPPoS example with USB DTE ([53b5933](https://github.com/espressif/esp-protocols/commit/53b5933))
- Allow USB DTE reconnection ([bf84ae9](https://github.com/espressif/esp-protocols/commit/bf84ae9))
- Add ConsoleCommand destructor ([a89a0ab](https://github.com/espressif/esp-protocols/commit/a89a0ab))
- esp_modem_get_gnss_power_mode (#136) ([fe536e4](https://github.com/espressif/esp-protocols/commit/fe536e4))
- remove unused Config Parameters ! ([55b4775](https://github.com/espressif/esp-protocols/commit/55b4775))
## [0.1.24](https://github.com/espressif/esp-protocols/commits/9b48b0a)
### Features
- Make some CMUX params compile-time configurable ([25ac2d9](https://github.com/espressif/esp-protocols/commit/25ac2d9))
### Bug Fixes
- CMUX to ignore MSC frames ([ce175df](https://github.com/espressif/esp-protocols/commit/ce175df), [#140](https://github.com/espressif/esp-protocols/issues/140))
- Fix CRLF endlines in examples ([07a347f](https://github.com/espressif/esp-protocols/commit/07a347f))
- Console example to use configurable flow-ctrl ([d9c9681](https://github.com/espressif/esp-protocols/commit/d9c9681))
### Updated
- update(esp_modem): Bump component version ([9b48b0a](https://github.com/espressif/esp-protocols/commit/9b48b0a))
- Allow error handler register in C ([62cb235](https://github.com/espressif/esp-protocols/commit/62cb235))
## [0.1.23](https://github.com/espressif/esp-protocols/commits/04c711f)
### Features
- Add exit PPP in example ([290197c](https://github.com/espressif/esp-protocols/commit/290197c))
### Updated
- Move common C definitions in to separate header ([04c711f](https://github.com/espressif/esp-protocols/commit/04c711f))
- Minor formatting fix and spelling ([accf924](https://github.com/espressif/esp-protocols/commit/accf924))
- extended the modem_console example. (#120) ([ef0e48a](https://github.com/espressif/esp-protocols/commit/ef0e48a))
## [0.1.22](https://github.com/espressif/esp-protocols/commits/187ef76)
### Bug Fixes
- DTE command race of timeout vs reply's signal ([a871473](https://github.com/espressif/esp-protocols/commit/a871473), [#110](https://github.com/espressif/esp-protocols/issues/110))
- Correct timeouts for certain commands ([1029078](https://github.com/espressif/esp-protocols/commit/1029078), [#129](https://github.com/espressif/esp-protocols/issues/129))
- Make get_operator_name() return also ACT value ([0015e54](https://github.com/espressif/esp-protocols/commit/0015e54), [#128](https://github.com/espressif/esp-protocols/issues/128))
### Updated
- update(esp_modem): Bump component version ([187ef76](https://github.com/espressif/esp-protocols/commit/187ef76))
## [0.1.21](https://github.com/espressif/esp-protocols/commits/d07237b)
### Updated
- Fix IDF version resolution ([d07237b](https://github.com/espressif/esp-protocols/commit/d07237b))
- Fix format warnings ([98bf3ef](https://github.com/espressif/esp-protocols/commit/98bf3ef), [#79](https://github.com/espressif/esp-protocols/issues/79))
## [0.1.20](https://github.com/espressif/esp-protocols/commits/ae8479c)
### Bug Fixes
- Correct exit of CMUX mode ([2099434](https://github.com/espressif/esp-protocols/commit/2099434), [#103](https://github.com/espressif/esp-protocols/issues/103))
- Add filename/line info to exception message ([89e1bd2](https://github.com/espressif/esp-protocols/commit/89e1bd2))
### Updated
- Expose set_error_cb method ([ae8479c](https://github.com/espressif/esp-protocols/commit/ae8479c))
## [0.1.19](https://github.com/espressif/esp-protocols/commits/469f953)
### Features
- Add optional ACT to operator-name ([a286634](https://github.com/espressif/esp-protocols/commit/a286634), [#80](https://github.com/espressif/esp-protocols/issues/80))
### Bug Fixes
- Add missing set_pdp_context() to C-API ([4980ac8](https://github.com/espressif/esp-protocols/commit/4980ac8))
### Updated
- updated package version to 0.1.19 ([469f953](https://github.com/espressif/esp-protocols/commit/469f953))
- CI: Fix build issues ([6e4e4fa](https://github.com/espressif/esp-protocols/commit/6e4e4fa))
- esp_err_to_name (IDFGH-7793) (#78) ([d1129f3](https://github.com/espressif/esp-protocols/commit/d1129f3))
## [0.1.18](https://github.com/espressif/esp-protocols/commits/e8145fc)
### Features
- Add CMUX mode to C-API ([3fd4391](https://github.com/espressif/esp-protocols/commit/3fd4391), [#41](https://github.com/espressif/esp-protocols/issues/41))
- Add support to CMUX exit ([a16aab6](https://github.com/espressif/esp-protocols/commit/a16aab6), [#37](https://github.com/espressif/esp-protocols/issues/37))
### Bug Fixes
- Update ap2ppp example to recover network on disconnection ([a243d7e](https://github.com/espressif/esp-protocols/commit/a243d7e), [#44](https://github.com/espressif/esp-protocols/issues/44))
- Implement movable unique_buffer to bundle data, size, ptr ([66e6d4c](https://github.com/espressif/esp-protocols/commit/66e6d4c))
- DTE should own both command and data terminal ([f3ff98b](https://github.com/espressif/esp-protocols/commit/f3ff98b))
- Update CMUX example to use CMUX mode automatically ([58a0b57](https://github.com/espressif/esp-protocols/commit/58a0b57))
- Improve PPP exit sequence ([1e0aefd](https://github.com/espressif/esp-protocols/commit/1e0aefd), [#47](https://github.com/espressif/esp-protocols/issues/47))
### Updated
- Ignore format warnings ([e8145fc](https://github.com/espressif/esp-protocols/commit/e8145fc))
- Allow to customize uart source_clk ([d723fb7](https://github.com/espressif/esp-protocols/commit/d723fb7))
- Add "at" api for custom commands ([0cf08fb](https://github.com/espressif/esp-protocols/commit/0cf08fb))
## [0.1.17](https://github.com/espressif/esp-protocols/commits/5addf9e)
### Features
- Bumped version number to 0.1.17 ([5addf9e](https://github.com/espressif/esp-protocols/commit/5addf9e))
### Bug Fixes
- Support 2 byte size packets ([128c0a2](https://github.com/espressif/esp-protocols/commit/128c0a2), [#46](https://github.com/espressif/esp-protocols/issues/46))
- Correction of switching to CMUX ([503218b](https://github.com/espressif/esp-protocols/commit/503218b), [#33](https://github.com/espressif/esp-protocols/issues/33))
### Updated
- Fix param description for get_operator_name() ([a661e51](https://github.com/espressif/esp-protocols/commit/a661e51))
- Update: Removed stringstream to decrease static sizes ([3ced2d9](https://github.com/espressif/esp-protocols/commit/3ced2d9))
- Update: Renamed list_in to be type-specific Update: Removed modem-specific comment ([ba88d7f](https://github.com/espressif/esp-protocols/commit/ba88d7f))
- Update: Changed tests to coincide with new initial esp_modem mode ([4f3c429](https://github.com/espressif/esp-protocols/commit/4f3c429))
- typo ([52de8f1](https://github.com/espressif/esp-protocols/commit/52de8f1))
- Update: Removed duplicate power down function Add: gnss power mode function ([e98cf16](https://github.com/espressif/esp-protocols/commit/e98cf16))
- Update: Formatting ([be3d2ec](https://github.com/espressif/esp-protocols/commit/be3d2ec))
- Add: Sim7600 extended support ([15ed885](https://github.com/espressif/esp-protocols/commit/15ed885))
- Add: Support for SIM7000 modules ([0733ea8](https://github.com/espressif/esp-protocols/commit/0733ea8))
- Update: modem_mode::UNDEF initially ([15cbc9b](https://github.com/espressif/esp-protocols/commit/15cbc9b))
- Add: sim7070 support ([bb7f198](https://github.com/espressif/esp-protocols/commit/bb7f198))
- Add: Expanded modem_command_library with more "standard" commands ([d3f7ea6](https://github.com/espressif/esp-protocols/commit/d3f7ea6))
- Fix DCE selection in pppos_client example ([d191a72](https://github.com/espressif/esp-protocols/commit/d191a72))
- Fix AT command in set_data_mode_sim8xx() for SIM800 modem device ([cc0d527](https://github.com/espressif/esp-protocols/commit/cc0d527))
## [0.1.16](https://github.com/espressif/esp-protocols/commits/74040cf)
### Updated
- Extend modem_console example with USB DTE ([74040cf](https://github.com/espressif/esp-protocols/commit/74040cf))
## [0.1.15](https://github.com/espressif/esp-protocols/commits/1f5eb39)
### Updated
- Fix IDFv5.0 include paths ([1f5eb39](https://github.com/espressif/esp-protocols/commit/1f5eb39))
## [0.1.14](https://github.com/espressif/esp-protocols/commits/745201b)
### Bug Fixes
- missing default statement in a switch in the modem_console example ([325a193](https://github.com/espressif/esp-protocols/commit/325a193))
- add virtual destructors to ModuleIf and CommandableIf ([face03e](https://github.com/espressif/esp-protocols/commit/face03e))
### Updated
- build: fix issue with passing cxx_std option, a common workaround ([745201b](https://github.com/espressif/esp-protocols/commit/745201b))
- add(esp_modem): Add unit test to check polymorphic delete ([e54b240](https://github.com/espressif/esp-protocols/commit/e54b240))
- Implement esp_modem_sync for the C API ([8b3d420](https://github.com/espressif/esp-protocols/commit/8b3d420))
## [0.1.13](https://github.com/espressif/esp-protocols/commits/2cb74cf)
### Bug Fixes
- Update the test to exersise CBC parser ([d879e82](https://github.com/espressif/esp-protocols/commit/d879e82))
- Fix battery status parse ([4f1d31f](https://github.com/espressif/esp-protocols/commit/4f1d31f))
- Read module name with AT commands ([8417e23](https://github.com/espressif/esp-protocols/commit/8417e23))
- linux port to work with lwip-2.1.2 ([8465b14](https://github.com/espressif/esp-protocols/commit/8465b14))
### Updated
- Update(esp_modem): Bump component version ([2cb74cf](https://github.com/espressif/esp-protocols/commit/2cb74cf))
## [0.1.12](https://github.com/espressif/esp-protocols/commits/5d9ad9c)
### Updated
- Update FreeRTOS EventQueueHandle_t forward declaration ([5d9ad9c](https://github.com/espressif/esp-protocols/commit/5d9ad9c))
## [0.1.11](https://github.com/espressif/esp-protocols/commits/9649876)
### Updated
- New version to publish to component registry ([9649876](https://github.com/espressif/esp-protocols/commit/9649876))
- Docs: Add links to GitHub pages ([cf990d1](https://github.com/espressif/esp-protocols/commit/cf990d1))
- Add missing AT commands to plain C-API ([5299b42](https://github.com/espressif/esp-protocols/commit/5299b42))
- CI/Docs: Generate docs locally before uploading to registry ([2c21aa1](https://github.com/espressif/esp-protocols/commit/2c21aa1))
- CI/Docs: Add jobs to deploy component docs ([b9ff1e4](https://github.com/espressif/esp-protocols/commit/b9ff1e4))
- Update Task handle and Event Group handle to match freertos v10.4.3 ([5888717](https://github.com/espressif/esp-protocols/commit/5888717))
- Examples: Fix print format for http_client() API ([01e2a9c](https://github.com/espressif/esp-protocols/commit/01e2a9c))
- Examples: Fix build error when SIM needs no PIN ([c8c24ed](https://github.com/espressif/esp-protocols/commit/c8c24ed))
- Examples: Use bigger 4M flash for OTA example ([b380ded](https://github.com/espressif/esp-protocols/commit/b380ded))
## [0.1.9](https://github.com/espressif/esp-protocols/commits/2a2d270)
### Updated
- Fix CMake3.5 build with no cxx_std_17 feature ([2a2d270](https://github.com/espressif/esp-protocols/commit/2a2d270))
## [0.1.8](https://github.com/espressif/esp-protocols/commits/9dd1bd5)
### Updated
- 0.1.8: Update comonent version ([9dd1bd5](https://github.com/espressif/esp-protocols/commit/9dd1bd5))
- Add pre upload script to deploy the docs before component upload ([918db0d](https://github.com/espressif/esp-protocols/commit/918db0d))
- Minor correction of the docs ([c1b1330](https://github.com/espressif/esp-protocols/commit/c1b1330))
- Examples/console: Remove unnecessary event-base check on IP handler ([fb7295e](https://github.com/espressif/esp-protocols/commit/fb7295e))
- Examples: Extend CMux client default stack size for the main task ([8236b3d](https://github.com/espressif/esp-protocols/commit/8236b3d))
- CMUX: Refactor the protocol decoder to multiple methods per cmux state ([fb6029b](https://github.com/espressif/esp-protocols/commit/fb6029b))
- Factory: Rename Builder class to Creator, since it's not 100% builder pattern ([6e34954](https://github.com/espressif/esp-protocols/commit/6e34954))
- Formal updates per code review ([148a930](https://github.com/espressif/esp-protocols/commit/148a930))
- Docs: Update CMux collaboration diagram to resemble composite ([1fb9150](https://github.com/espressif/esp-protocols/commit/1fb9150))
- Applied astyle code formatting ([a61e9e2](https://github.com/espressif/esp-protocols/commit/a61e9e2))
- Minor corrections per code review ([dc64f86](https://github.com/espressif/esp-protocols/commit/dc64f86))
- Bulk replace header guards to use ([3332c27](https://github.com/espressif/esp-protocols/commit/3332c27))
- Host test fix: renamed Loopback inherited member ([84b0dcf](https://github.com/espressif/esp-protocols/commit/84b0dcf))
- Update documentation and minor fixes ([e0e6585](https://github.com/espressif/esp-protocols/commit/e0e6585))
## [0.1.7](https://github.com/espressif/esp-protocols/commits/28433de)
### Updated
- Update version to 0.1.7 -- support socket VFS ([28433de](https://github.com/espressif/esp-protocols/commit/28433de))
- Reworked decouple resources from the file system ([8f17a90](https://github.com/espressif/esp-protocols/commit/8f17a90))
- Make the component compatible with IDFv4.1, v4.2, v4.3 ([69ad3ea](https://github.com/espressif/esp-protocols/commit/69ad3ea))
## [0.1.6](https://github.com/espressif/esp-protocols/commits/a67d749)
### Updated
- Bump the version and upload the component ([a67d749](https://github.com/espressif/esp-protocols/commit/a67d749))
- Updated per review comments ([ab93c13](https://github.com/espressif/esp-protocols/commit/ab93c13))
## [0.1.5](https://github.com/espressif/esp-protocols/commits/90641c8)
### Updated
- Moved to component folder ([90641c8](https://github.com/espressif/esp-protocols/commit/90641c8))

View File

@ -17,5 +17,5 @@ Get started with one of the examples:
## Documentation
* Continue with esp-modem [brief overview](docs/README.md)
* View the full [html documentation](https://espressif.github.io/esp-protocols/esp_modem/index.html)
* Continue with esp-modem [brief overview](https://github.com/espressif/esp-protocols/tree/master/docs/esp_modem/en/README.rst)
* View the full [html documentation](https://docs.espressif.com/projects/esp-protocols/esp_modem/docs/latest/index.html)

View File

@ -1,92 +0,0 @@
# ESP MODEM
This component is used to communicate with modems in the command mode (using AT commands), as well as the data mode
(over PPPoS protocol).
The modem device is modeled with a DCE (Data Communication Equipment) object, which is composed of:
* DTE (Data Terminal Equipment), which abstracts the terminal (currently only UART implemented).
* PPP Netif representing a network interface communicating with the DTE using PPP protocol.
* Module abstracting the specific device model and its commands.
```
+-----+
| DTE |--+
+-----+ | +-------+
+-->| DCE |
+-------+ | |o--- set_mode(command/data)
| Module|--->| |
+-------+ | |o--- send_commands
+->| |
+------+ | +-------+
| PPP |--+
| netif|------------------> network events
+------+
```
## Modem components
### DCE
This is the basic operational unit of the esp_modem component, abstracting a specific module in software,
which is basically configured by
* the I/O communication media (UART), defined by the DTE configuration
* the specific command library supported by the device model, defined with the module type
* network interface configuration (PPPoS config in lwip)
After the object is created, the application interaction with the DCE is in
* issuing specific commands to the modem
* switching between data and command mode
### DTE
Is an abstraction of the physical interface connected to the modem. Current implementation supports only UART
### PPP netif
Is used to attach the specific network interface to a network communication protocol used by the modem. Currently implementation supports only PPPoS protocol.
### Module
Abstraction of the specific modem device. Currently the component supports SIM800, BG96, SIM7600.
## Use cases
Users interact with the esp-modem using the DCE's interface, to basically
* Switch between command and data mode to connect to the internet via cellular network.
* Send various commands to the device (e.g. send SMS)
The applications typically register handlers for network events to receive notification on the network availability and
IP address changes.
Common use cases of the esp-modem are also listed as the examples:
* `examples/pppos_client` -- simple client which reads some module properties and switches to the data mode to connect to a public mqtt broker.
* `examples/modem_console` -- is an example to exercise all possible module commands in a console application.
* `examples/ap_to_pppos` -- this example focuses on the network connectivity of the esp-modem and provides a WiFi AP that forwards packets (and uses NAT) to and from the PPPoS connection.
## Extensibility
### CMUX
Implementation of virtual terminals is an experimental feature, which allows users to also issue commands in the data mode,
after creating multiple virtual terminals, designating some of them solely to data mode, others solely to command mode.
### DTE's
Currently, we support only UART (and USB as a preview feature), but modern modules support other communication interfaces, such as USB, SPI.
### Other devices
Adding a new device is a must-have requirement for the esp-modem component. Different modules support different commands,
or some commands might have a different implementation. Adding a new device means to provide a new implementation
as a class derived from `GenericModule`, where we could add new commands or modify the existing ones.
## Configuration
Modem abstraction is configurable both compile-time and run-time.
### Component Kconfig
Compile-time configuration is provided using menuconfig. Please check the description for the CMUX mode configuration options.
### Runtime configuration
Is defined using standard configuration structures for `DTE` and `DCE` objects separately. Please find documentation of
* :cpp:class:`esp_modem_dte_config_t`
* :cpp:class:`esp_modem_dce_config_t`

View File

@ -1,23 +0,0 @@
# Cleanup the generated html
rm -rf html
# Cleans example and test build dirs (to reduce the component size before upload)
rm -rf ../examples/ap_to_pppos/build/ ../examples/simple_cmux_client/build/ ../examples/pppos_client/build/ ../examples/linux_modem/build/ ../examples/modem_console/build ../test/host_test/build/ ../test/target/build/
# Generate C++ API header of the DCE
cat ../include/generate/esp_modem_command_declare.inc | clang++ -E -P -CC -xc++ -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' > esp_modem_dce.hpp
# Generate C API header of the modem_api.h
cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -CC -xc -I../include -DGENERATE_DOCS - | sed -n '1,/DCE command documentation/!p' > esp_modem_api_commands.h
# RST with links to C++ API
cat ../include/generate/esp_modem_command_declare.inc | clang -E -P -xc -I../include -DGENERATE_DOCS -DGENERATE_RST_LINKS - | sed 's/NL/\n/g' > cxx_api_links.rst
# Run doxygen
doxygen
# Generate the docs
python -u -m sphinx.cmd.build -b html . html
# Cleanup the doxygen xml's and temporary headers
rm -rf xml esp_modem_api_commands.h esp_modem_dce.hpp cxx_api_links.rst

View File

@ -1,36 +0,0 @@
# Internal design
## Design decisions
* Use C++ with additional C API
* Use exceptions
- Use macro wrapper over `try-catch` blocks when exceptions off (use `abort()` if `THROW()`)
* Initializes and allocates in the constructor (might throw)
- easier code with exceptions ON, with exceptions OFF alloc/init failures are not treated as runtime error (program aborts)
- break down long initialization in constructor into more private methods
* Implements different devices using inheritance from `GenericModule`, which is the most general implementation of a common modem
- Internally uses templates with device specialization (modeled as `DCE<SpecificModule>`) which could be used as well for some special cases,
such as implantation of a minimal device (ModuleIf), add new AT commands (oOnly in compile time), or using the Module with DTE only (no DCE, no Netif) for sending AT commands without network
## DCE collaboration model
The diagram describes how the DCE class collaborates with DTE, PPP and the device abstraction
![DCE_architecture](DCE_DTE_collaboration.png)
## Terminal inheritance
Terminal is a class which can read or write data, and can handle callbacks when data are available. UART specialization
is provided implementing these method using the uart driver.
## CMUX terminal
The below diagram depicts the idea of using CMUX terminal mode using the CMuxInstance class which is a terminal
(it implements the basic read/write methods) interfacing arbitrary number of virtual terminals,
but at the same time it is also composed of CMux class, which consumes the original terminal and uses its read/write methods
to multiplex the terminal.
![CMUX Terminal](CMux_collaboration.png)

View File

@ -0,0 +1,7 @@
components/esp_modem/examples/ap_to_pppos:
disable:
- if: IDF_TARGET in ["esp32h2"]
components/esp_modem/examples/modem_console:
disable:
- if: IDF_TARGET in ["esp32h2"]

View File

@ -7,4 +7,6 @@ endif()
idf_component_register(SRCS "ap_to_pppos.c"
${NETWORK_DCE}
INCLUDE_DIRS ".")
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
# Ignore strict prototypes, as the network_dce.h can used in both C and C++ compilation
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-strict-prototypes")

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -14,6 +14,7 @@
#include "esp_log.h"
#include "esp_idf_version.h"
#include "nvs_flash.h"
#include "lwip/netif.h"
#include "lwip/lwip_napt.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
@ -38,7 +39,7 @@ 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)
{
ESP_LOGD(TAG, "IP event! %d", event_id);
ESP_LOGD(TAG, "IP event! %" PRId32, 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;

View File

@ -1,6 +1,7 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.8)
set(CMAKE_CXX_STANDARD 17)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(modem-console)

View File

@ -1,5 +1,6 @@
idf_component_register(SRCS "modem_console_main.cpp"
"console_helper.cpp"
"my_module_dce.cpp"
"httpget_handle.c"
"ping_handle.c"
REQUIRES console esp_http_client nvs_flash

View File

@ -16,17 +16,18 @@ menu "Example Configuration"
endchoice
choice EXAMPLE_MODEM_DEVICE
depends on EXAMPLE_SERIAL_CONFIG_UART
prompt "Choose supported modem device (DCE)"
default EXAMPLE_MODEM_DEVICE_BG96
default EXAMPLE_MODEM_DEVICE_SHINY
help
Select modem device connected to the ESP DTE.
config EXAMPLE_MODEM_DEVICE_SHINY
depends on EXAMPLE_SERIAL_CONFIG_UART
bool "SHINY"
help
SHINY is a GSM/GPRS module.
It supports SHINY.
config EXAMPLE_MODEM_DEVICE_SIM800
depends on EXAMPLE_SERIAL_CONFIG_UART
bool "SIM800"
help
SIMCom SIM800L is a GSM/GPRS module.
@ -36,10 +37,12 @@ menu "Example Configuration"
help
Quectel BG96 is a series of LTE Cat M1/Cat NB1/EGPRS module.
config EXAMPLE_MODEM_DEVICE_SIM7000
depends on EXAMPLE_SERIAL_CONFIG_UART
bool "SIM7000"
help
SIM7000 is a Multi-Band LTE-FDD and GSM/GPRS/EDGE module.
config EXAMPLE_MODEM_DEVICE_SIM7070
depends on EXAMPLE_SERIAL_CONFIG_UART
bool "SIM7070"
help
SIM7070 is Multi-Band CAT M and NB IoT module.
@ -47,6 +50,11 @@ menu "Example Configuration"
bool "SIM7600"
help
SIM7600 is a Multi-Band LTE-TDD/LTE-FDD/HSPA+ and GSM/GPRS/EDGE module.
config EXAMPLE_MODEM_DEVICE_A7670
depends on EXAMPLE_SERIAL_CONFIG_USB
bool "A7670"
help
A7670X is Multi-Band LTE-FDD/LTE-TDD/GSM/GPRS/EDGE module.
endchoice
config EXAMPLE_MODEM_PPP_APN

View File

@ -3,10 +3,10 @@ dependencies:
## Required IDF version
idf: ">=4.1.0"
espressif/esp_modem:
version: "^0.1.20"
version: "^1.0.0"
override_path: "../../../"
espressif/esp_modem_usb_dte:
version: "^1.0.0"
version: "^1.1.0"
rules:
- if: "idf_version >=4.4"
- if: "target in [esp32s2, esp32s3]"

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -48,9 +48,9 @@
} } while (0)
/**
* Please update the default APN name here (this could be updated runtime)
* Default APN name is taken from Kconfig (this could be updated runtime)
*/
#define DEFAULT_APN "my_apn"
#define DEFAULT_APN CONFIG_EXAMPLE_MODEM_PPP_APN
#define GPIO_OUTPUT_PWRKEY (gpio_num_t)CONFIG_EXAMPLE_MODEM_PWRKEY_PIN
#define GPIO_OUTPUT_PIN_SEL (1ULL<<GPIO_OUTPUT_PWRKEY)
@ -89,6 +89,14 @@ void wakeup_modem(void)
vTaskDelay(pdMS_TO_TICKS(2000));
}
#ifdef CONFIG_EXAMPLE_MODEM_DEVICE_SHINY
command_result handle_urc(uint8_t *data, size_t len)
{
ESP_LOG_BUFFER_HEXDUMP("on_read", data, len, ESP_LOG_INFO);
return command_result::TIMEOUT;
}
#endif
extern "C" void app_main(void)
{
static RTC_RODATA_ATTR char apn_rtc[20] = DEFAULT_APN;
@ -122,19 +130,19 @@ extern "C" void app_main(void)
dte_config.dte_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE / 2;
auto uart_dte = create_uart_dte(&dte_config);
#if CONFIG_EXAMPLE_MODEM_DEVICE_SHINY == 1
#if defined(CONFIG_EXAMPLE_MODEM_DEVICE_SHINY)
ESP_LOGI(TAG, "Initializing esp_modem for the SHINY module...");
auto dce = create_shiny_dce(&dce_config, uart_dte, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
#elif defined(CONFIG_EXAMPLE_MODEM_DEVICE_BG96)
ESP_LOGI(TAG, "Initializing esp_modem for the BG96 module...");
auto dce = create_BG96_dce(&dce_config, uart_dte, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 == 1
#elif defined(CONFIG_EXAMPLE_MODEM_DEVICE_SIM800)
ESP_LOGI(TAG, "Initializing esp_modem for the SIM800 module...");
auto dce = create_SIM800_dce(&dce_config, uart_dte, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7000 == 1
#elif defined(CONFIG_EXAMPLE_MODEM_DEVICE_SIM7000)
ESP_LOGI(TAG, "Initializing esp_modem for the SIM7000 module...");
auto dce = create_SIM7000_dce(&dce_config, uart_dte, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070 == 1
#elif defined(CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070)
ESP_LOGI(TAG, "Initializing esp_modem for the SIM7070 module...");
auto dce = create_SIM7070_dce(&dce_config, uart_dte, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
@ -149,7 +157,18 @@ extern "C" void app_main(void)
#elif defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
while (1) {
exit_signal.clear(1);
struct esp_modem_usb_term_config usb_config = ESP_MODEM_DEFAULT_USB_CONFIG(0x2C7C, 0x0296, 2); // VID, PID and interface num of BG96 modem
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
ESP_LOGI(TAG, "Initializing esp_modem for the BG96 module...");
struct esp_modem_usb_term_config usb_config = ESP_MODEM_BG96_USB_CONFIG();
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
ESP_LOGI(TAG, "Initializing esp_modem for the SIM7600 module...");
struct esp_modem_usb_term_config usb_config = ESP_MODEM_SIM7600_USB_CONFIG();
#elif CONFIG_EXAMPLE_MODEM_DEVICE_A7670 == 1
ESP_LOGI(TAG, "Initializing esp_modem for the A7670 module...");
struct esp_modem_usb_term_config usb_config = ESP_MODEM_A7670_USB_CONFIG();
#else
#error USB modem not selected
#endif
const 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);
@ -159,7 +178,13 @@ extern "C" void app_main(void)
exit_signal.set(1);
}
});
#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_SIM7600 == 1 || CONFIG_EXAMPLE_MODEM_DEVICE_A7670 == 1
std::unique_ptr<DCE> dce = create_SIM7600_dce(&dce_config, dte, esp_netif);
#else
#error USB modem not selected
#endif
#else
#error Invalid serial connection to modem.
@ -286,8 +311,9 @@ extern "C" void app_main(void)
const ConsoleCommand GetOperatorName("get_operator_name", "reads the operator name", no_args, [&](ConsoleCommand * c) {
std::string operator_name;
int act;
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()));
CHECK_ERR(dce->get_operator_name(operator_name, act), ESP_LOGI(TAG, "OK. Operator name: %s", operator_name.c_str()));
});
const struct GenericCommandArgs {
@ -339,6 +365,20 @@ extern "C" void app_main(void)
ESP_LOGI(TAG, "Resetting the module...");
CHECK_ERR(dce->reset(), ESP_LOGI(TAG, "OK"));
});
#ifdef CONFIG_EXAMPLE_MODEM_DEVICE_SHINY
const ConsoleCommand HandleURC("urc", "toggle urc handling", no_args, [&](ConsoleCommand * c) {
static int cnt = 0;
if (++cnt % 2) {
ESP_LOGI(TAG, "Adding URC handler");
dce->set_on_read(handle_urc);
} else {
ESP_LOGI(TAG, "URC removed");
dce->set_on_read(nullptr);
}
return 0;
});
#endif
const struct SetApn {
SetApn(): apn(STR1, nullptr, nullptr, "<apn>", "APN (Access Point Name)") {}
CommandArgs apn;

View File

@ -0,0 +1,114 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* Modem console example: Custom DCE
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 <cstring>
#include "cxx_include/esp_modem_api.hpp"
#include "cxx_include/esp_modem_dce_module.hpp"
#include "generate/esp_modem_command_declare.inc"
#include "my_module_dce.hpp"
using namespace esp_modem;
//
// Define preprocessor's forwarding to dce_commands definitions
//
// Helper macros to handle multiple arguments of declared API
#define ARGS0
#define ARGS1 , p1
#define ARGS2 , p1 , p2
#define ARGS3 , p1 , p2 , p3
#define ARGS4 , p1 , p2 , p3, p4
#define ARGS5 , p1 , p2 , p3, p4, p5
#define ARGS6 , p1 , p2 , p3, p4, p5, p6
#define _ARGS(x) ARGS ## x
#define ARGS(x) _ARGS(x)
#define CMD_OK (1)
#define CMD_FAIL (2)
//
// Repeat all declarations and forward to the AT commands defined in esp_modem::dce_commands:: namespace
//
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, arg_nr, ...) \
return_type Shiny::DCE::name(__VA_ARGS__) { return esp_modem::dce_commands::name(this ARGS(arg_nr) ); }
DECLARE_ALL_COMMAND_APIS(return_type name(...) )
#undef ESP_MODEM_DECLARE_DCE_COMMAND
std::unique_ptr<Shiny::DCE> create_shiny_dce(const esp_modem::dce_config *config,
std::shared_ptr<esp_modem::DTE> dte,
esp_netif_t *netif)
{
return Shiny::Factory::create(config, std::move(dte), netif);
}
/**
* @brief Definition of the command API, which makes the Shiny::DCE "command-able class"
* @param cmd Command to send
* @param got_line Recv line callback
* @param time_ms timeout in ms
* @param separator line break separator
* @return OK, FAIL or TIMEOUT
*/
command_result Shiny::DCE::command(const std::string &cmd, got_line_cb got_line, uint32_t time_ms, const char separator)
{
if (!handling_urc) {
return dte->command(cmd, got_line, time_ms, separator);
}
handle_cmd = got_line;
signal.clear(CMD_OK | CMD_FAIL);
esp_modem::DTE_Command command{cmd};
dte->write(command);
signal.wait_any(CMD_OK | CMD_FAIL, time_ms);
handle_cmd = nullptr;
if (signal.is_any(CMD_OK)) {
return esp_modem::command_result::OK;
}
if (signal.is_any(CMD_FAIL)) {
return esp_modem::command_result::FAIL;
}
return esp_modem::command_result::TIMEOUT;
}
/**
* @brief Handle received data
*
* @param data Data received from the device
* @param len Length of the data
* @return standard command return code (OK|FAIL|TIMEOUT)
*/
command_result Shiny::DCE::handle_data(uint8_t *data, size_t len)
{
if (std::memchr(data, '\n', len)) {
if (handle_urc) {
handle_urc(data, len);
}
if (handle_cmd) {
auto ret = handle_cmd(data, len);
if (ret == esp_modem::command_result::TIMEOUT) {
return command_result::TIMEOUT;
}
if (ret == esp_modem::command_result::OK) {
signal.set(CMD_OK);
}
if (ret == esp_modem::command_result::FAIL) {
signal.set(CMD_FAIL);
}
}
}
return command_result::TIMEOUT;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -11,6 +11,8 @@
#pragma once
#include <utility>
#include "cxx_include/esp_modem_dce_factory.hpp"
#include "cxx_include/esp_modem_dce_module.hpp"
@ -28,13 +30,84 @@ public:
}
};
namespace Shiny {
using namespace esp_modem;
class DCE : public esp_modem::DCE_T<MyShinyModem>, public CommandableIf {
public:
using DCE_T<MyShinyModem>::DCE_T;
command_result
command(const std::string &cmd, got_line_cb got_line, uint32_t time_ms) override
{
return command(cmd, got_line, time_ms, '\n');
}
command_result
command(const std::string &cmd, got_line_cb got_line, uint32_t time_ms, const char separator) override;
int write(uint8_t *data, size_t len) override
{
return dte->write(data, len);
}
void on_read(got_line_cb on_data) override
{
return dte->on_read(on_data);
}
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \
esp_modem::return_type name(__VA_ARGS__);
DECLARE_ALL_COMMAND_APIS(forwards name(...))
#undef ESP_MODEM_DECLARE_DCE_COMMAND
void set_on_read(esp_modem::got_line_cb on_read_cb)
{
if (on_read_cb == nullptr) {
handling_urc = false;
handle_urc = nullptr;
dte->on_read(nullptr);
return;
}
handle_urc = std::move(on_read_cb);
dte->on_read([this](uint8_t *data, size_t len) {
this->handle_data(data, len);
return command_result::TIMEOUT;
});
handling_urc = true;
}
private:
got_line_cb handle_urc{nullptr};
got_line_cb handle_cmd{nullptr};
SignalGroup signal;
bool handling_urc {false};
command_result handle_data(uint8_t *data, size_t len);
};
class Factory: public ::esp_modem::dce_factory::Factory {
public:
static std::unique_ptr<DCE> create(const esp_modem::dce_config *config,
std::shared_ptr<esp_modem::DTE> dte,
esp_netif_t *netif)
{
return build_generic_DCE<MyShinyModem, DCE, std::unique_ptr<DCE>>(config, std::move(dte), netif);
}
};
} // namespace Shiny
/**
* @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module
* @return unique pointer of the resultant DCE
*/
std::unique_ptr<esp_modem::DCE> create_shiny_dce(const esp_modem::dce_config *config,
std::unique_ptr<Shiny::DCE> create_shiny_dce(const esp_modem::dce_config *config,
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);
}
esp_netif_t *netif);

View File

@ -1 +1,2 @@
CONFIG_IDF_TARGET="esp32s2"
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y

View File

@ -1 +1,2 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y

View File

@ -0,0 +1,9 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.8)
set(CMAKE_CXX_STANDARD 17)
set(EXTRA_COMPONENT_DIRS "../..")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(modem_tcp_client)

View File

@ -0,0 +1,10 @@
# Modem TCP client
(See the README.md file in the upper level 'examples' directory for more information about examples.)
## Overview
This example demonstrates how to act as a MQTT client using modem's TCP commands (provided, the device supports "socket" related commands)
### Supported IDF versions
This example is supported from IDF `v4.4`.

View File

@ -0,0 +1,11 @@
if (CONFIG_EXAMPLE_MODEM_DEVICE_BG96)
set(device_srcs sock_commands_bg96.cpp)
elseif(CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600)
set(device_srcs sock_commands_sim7600.cpp)
endif()
idf_component_register(SRCS "modem_client.cpp"
"sock_dce.cpp"
"${device_srcs}"
INCLUDE_DIRS ".")
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@ -0,0 +1,96 @@
menu "Example Configuration"
choice EXAMPLE_MODEM_DEVICE
prompt "Choose supported modem device (DCE)"
default EXAMPLE_MODEM_DEVICE_BG96
help
Select modem device connected to the ESP DTE.
config EXAMPLE_MODEM_DEVICE_BG96
bool "BG96"
help
Quectel BG96 is a series of LTE Cat M1/Cat NB1/EGPRS module.
config EXAMPLE_MODEM_DEVICE_SIM7600
bool "SIM7600"
help
SIM7600 is Multi-Band LTE-TDD/LTE-FDD/HSPA+ and GSM/GPRS/EDGE module
endchoice
config EXAMPLE_MODEM_APN
string "Set MODEM APN"
default "internet"
help
Set APN (Access Point Name), a logical name to choose data network
menu "UART Configuration"
config EXAMPLE_MODEM_UART_TX_PIN
int "TXD Pin Number"
default 25
range 0 31
help
Pin number of UART TX.
config EXAMPLE_MODEM_UART_RX_PIN
int "RXD Pin Number"
default 26
range 0 31
help
Pin number of UART RX.
config EXAMPLE_MODEM_UART_RTS_PIN
int "RTS Pin Number"
default 27
range 0 31
help
Pin number of UART RTS.
config EXAMPLE_MODEM_UART_CTS_PIN
int "CTS Pin Number"
default 23
range 0 31
help
Pin number of UART CTS.
config EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE
int "UART Event Task Stack Size"
range 2000 6000
default 2048
help
Stack size of UART event task.
config EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY
int "UART Event Task Priority"
range 3 22
default 5
help
Priority of UART event task.
config EXAMPLE_MODEM_UART_EVENT_QUEUE_SIZE
int "UART Event Queue Size"
range 10 40
default 30
help
Length of UART event queue.
config EXAMPLE_MODEM_UART_PATTERN_QUEUE_SIZE
int "UART Pattern Queue Size"
range 10 40
default 20
help
Length of UART pattern queue.
config EXAMPLE_MODEM_UART_TX_BUFFER_SIZE
int "UART TX Buffer Size"
range 256 2048
default 512
help
Buffer size of UART TX buffer.
config EXAMPLE_MODEM_UART_RX_BUFFER_SIZE
int "UART RX Buffer Size"
range 256 2048
default 1024
help
Buffer size of UART RX buffer.
endmenu
endmenu

View File

@ -0,0 +1,140 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* PPPoS Client Example
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>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_netif.h"
#include "esp_netif_ppp.h"
#include "mqtt_client.h"
#include "esp_modem_config.h"
#include "cxx_include/esp_modem_api.hpp"
#include "sock_dce.hpp"
#include "esp_log.h"
#define BROKER_URL "mqtt.eclipseprojects.io"
static const char *TAG = "modem_client";
static EventGroupHandle_t event_group = NULL;
static const int CONNECT_BIT = BIT0;
static const int GOT_DATA_BIT = BIT2;
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
esp_mqtt_event_handle_t event = (esp_mqtt_event_handle_t)event_data;
esp_mqtt_client_handle_t client = event->client;
int msg_id;
switch ((esp_mqtt_event_id_t)event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
msg_id = esp_mqtt_client_subscribe(client, "/topic/esp-pppos", 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
msg_id = esp_mqtt_client_publish(client, "/topic/esp-pppos", "esp32-pppos", 0, 0, 0);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
xEventGroupSetBits(event_group, GOT_DATA_BIT);
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
break;
default:
ESP_LOGI(TAG, "MQTT other event id: %d", event->event_id);
break;
}
}
extern "C" void app_main(void)
{
/* Init and register system/core components */
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
event_group = xEventGroupCreate();
/* Configure and create the UART DTE */
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
/* setup UART specific configuration based on kconfig options */
dte_config.uart_config.tx_io_num = CONFIG_EXAMPLE_MODEM_UART_TX_PIN;
dte_config.uart_config.rx_io_num = CONFIG_EXAMPLE_MODEM_UART_RX_PIN;
dte_config.uart_config.rts_io_num = CONFIG_EXAMPLE_MODEM_UART_RTS_PIN;
dte_config.uart_config.cts_io_num = CONFIG_EXAMPLE_MODEM_UART_CTS_PIN;
dte_config.uart_config.rx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE;
dte_config.uart_config.tx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_TX_BUFFER_SIZE;
dte_config.uart_config.event_queue_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_QUEUE_SIZE;
dte_config.task_stack_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE * 2;
dte_config.task_priority = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY;
dte_config.dte_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE / 2;
auto dte = esp_modem::create_uart_dte(&dte_config);
assert(dte);
/* Configure the DCE */
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_APN);
/* create the DCE and initialize network manually (using AT commands) */
auto dce = sock_dce::create(&dce_config, std::move(dte));
if (!dce->init_network()) {
ESP_LOGE(TAG, "Failed to setup network");
return;
}
dce->init_sock(8883);
esp_mqtt_client_config_t mqtt_config = {};
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
mqtt_config.broker.address.uri = "mqtts://127.0.0.1";
mqtt_config.session.message_retransmit_timeout = 10000;
#else
mqtt_config.uri = "mqtt://127.0.0.1";
mqtt_config.message_retransmit_timeout = 10000;
#endif
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);
esp_mqtt_client_register_event(mqtt_client, static_cast<esp_mqtt_event_id_t>(ESP_EVENT_ANY_ID), mqtt_event_handler, NULL);
esp_mqtt_client_start(mqtt_client);
if (!dce->start(BROKER_URL, 8883)) {
ESP_LOGE(TAG, "Failed to start DCE");
return;
}
while (1) {
while (dce->perform_sock()) {
ESP_LOGV(TAG, "...performing");
}
ESP_LOGE(TAG, "Loop exit.. retrying");
// handle disconnections errors
if (!dce->init_network()) {
ESP_LOGE(TAG, "Failed to reinit network");
return;
}
if (!dce->start("test.mosquitto.org", 1883)) {
ESP_LOGI(TAG, "Network reinitialized, retrying");
}
}
}

View File

@ -0,0 +1,25 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "cxx_include/esp_modem_dte.hpp"
#include "cxx_include/esp_modem_dce_module.hpp"
#include "cxx_include/esp_modem_types.hpp"
#include "socket_commands.inc"
namespace sock_commands {
//using namespace esp_modem;
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \
esp_modem::return_type name(esp_modem::CommandableIf *t, ## __VA_ARGS__);
DECLARE_SOCK_COMMANDS(declare name(Commandable *p, ...);)
#undef ESP_MODEM_DECLARE_DCE_COMMAND
}

View File

@ -0,0 +1,348 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <charconv>
#include <cstring>
#include <sys/socket.h>
#include "sock_commands.hpp"
#include "cxx_include/esp_modem_command_library_utils.hpp"
#include "sock_dce.hpp"
static const char *TAG = "sock_commands";
namespace sock_commands {
using namespace esp_modem;
command_result net_open(CommandableIf *t)
{
ESP_LOGV(TAG, "%s", __func__ );
std::string out;
auto ret = dce_commands::generic_get_string(t, "AT+QISTATE?\r", out, 1000);
if (ret != command_result::OK) {
return ret;
}
if (out.find("+QISTATE: 0") != std::string::npos) {
ESP_LOGV(TAG, "%s", out.data() );
ESP_LOGD(TAG, "Already there");
return command_result::FAIL;
} else if (out.empty()) {
return dce_commands::generic_command(t, "AT+QIACT=1\r", "OK", "ERROR", 150000);
}
return command_result::FAIL;
}
command_result net_close(CommandableIf *t)
{
ESP_LOGV(TAG, "%s", __func__ );
dce_commands::generic_command(t, "AT+QICLOSE=0\r", "OK", "ERROR", 10000);
esp_modem::Task::Delay(1000);
return dce_commands::generic_command(t, "AT+QIDEACT=1\r", "OK", "ERROR", 40000);
}
command_result tcp_open(CommandableIf *t, const std::string &host, int port, int timeout)
{
ESP_LOGV(TAG, "%s", __func__ );
std::string ip_open = R"(AT+QIOPEN=1,0,"TCP",")" + host + "\"," + std::to_string(port) + "\r";
auto ret = dce_commands::generic_command(t, ip_open, "+QIOPEN: 0,0", "ERROR", timeout);
if (ret != command_result::OK) {
ESP_LOGE(TAG, "%s Failed", __func__ );
return ret;
}
return command_result::OK;
}
command_result tcp_close(CommandableIf *t)
{
ESP_LOGV(TAG, "%s", __func__ );
return dce_commands::generic_command(t, "AT+QICLOSE=0\r", "OK", "ERROR", 10000);
}
command_result tcp_send(CommandableIf *t, uint8_t *data, size_t len)
{
ESP_LOGV(TAG, "%s", __func__ );
assert(0); // Remove when fix done
return command_result::FAIL;
}
command_result tcp_recv(CommandableIf *t, uint8_t *data, size_t len, size_t &out_len)
{
ESP_LOGV(TAG, "%s", __func__ );
assert(0); // Remove when fix done
return command_result::FAIL;
}
command_result get_ip(CommandableIf *t, std::string &ip)
{
ESP_LOGV(TAG, "%s", __func__ );
std::string out;
auto ret = dce_commands::generic_get_string(t, "AT+QIACT?\r", out, 5000);
if (ret != command_result::OK) {
return ret;
}
auto pos = out.find("+QIACT: 1");
auto property = 0;
while (pos != std::string::npos) {
// Looking for: +QIACT: <contextID>,<context_state>,<context_type>,<IP_address>
if (property++ == 3) { // ip is after 3rd comma (as a 4rd property of QIACT string)
ip = out.substr(++pos);
// strip quotes if present
auto quote1 = ip.find('"');
auto quote2 = ip.rfind('"');
if (quote1 != std::string::npos && quote2 != std::string::npos) {
ip = ip.substr(quote1 + 1, quote2 - 1);
}
return command_result::OK;
}
pos = out.find(',', ++pos);
}
return command_result::FAIL;
}
} // sock_commands
namespace sock_dce {
void Responder::start_sending(size_t len)
{
data_to_send = len;
send_stat = 0;
send_cmd("AT+QISEND=0," + std::to_string(len) + "\r");
}
void Responder::start_receiving(size_t len)
{
send_cmd("AT+QIRD=0," + std::to_string(len) + "\r");
}
bool Responder::start_connecting(std::string host, int port)
{
send_cmd(R"(AT+QIOPEN=1,0,"TCP",")" + host + "\"," + std::to_string(port) + "\r");
return true;
}
Responder::ret Responder::recv(uint8_t *data, size_t len)
{
const int MIN_MESSAGE = 6;
size_t actual_len = 0;
auto *recv_data = (char *)data;
if (data_to_recv == 0) {
const std::string_view head = "+QIRD: ";
auto head_pos = std::search(recv_data, recv_data + len, head.begin(), head.end());
if (head_pos == nullptr) {
return ret::FAIL;
}
auto next_nl = (char *)memchr(head_pos + head.size(), '\n', MIN_MESSAGE);
if (next_nl == nullptr) {
return ret::FAIL;
}
if (std::from_chars(head_pos + head.size(), next_nl, actual_len).ec == std::errc::invalid_argument) {
ESP_LOGE(TAG, "cannot convert");
return ret::FAIL;
}
ESP_LOGD(TAG, "Received: actual len=%d", actual_len);
if (actual_len == 0) {
ESP_LOGD(TAG, "no data received");
return ret::FAIL;
}
if (actual_len > buffer_size) {
ESP_LOGE(TAG, "TOO BIG");
return ret::FAIL;
}
recv_data = next_nl + 1;
auto first_data_len = len - (recv_data - (char *)data) /* minus size of the command marker */;
if (actual_len > first_data_len) {
::send(sock, recv_data, first_data_len, 0);
data_to_recv = actual_len - first_data_len;
return ret::NEED_MORE_DATA;
}
::send(sock, recv_data, actual_len, 0);
} else if (data_to_recv > len) { // continue sending
::send(sock, recv_data, len, 0);
data_to_recv -= len;
return ret::NEED_MORE_DATA;
} else if (data_to_recv <= len) { // last read -> looking for "OK" marker
::send(sock, recv_data, data_to_recv, 0);
actual_len = data_to_recv;
}
// "OK" after the data
char *last_pos = nullptr;
if (actual_len + 1 + 2 /* OK */ > len) {
last_pos = (char *)memchr(recv_data + 1 + actual_len, 'O', MIN_MESSAGE);
if (last_pos == nullptr || last_pos[1] != 'K') {
data_to_recv = 0;
return ret::FAIL;
}
}
if (last_pos != nullptr && (char *)data + len - last_pos - 2 > MIN_MESSAGE) {
// check for async replies after the Recv header
std::string_view response((char *)last_pos + 2 /* OK */, (char *)data + len - last_pos);
check_async_replies(status::RECEIVING, response);
}
// check if some other data?
start_receiving(0);
data_to_recv = 0;
return ret::OK;
}
Responder::ret Responder::send(uint8_t *data, size_t len)
{
if (send_stat < 3) {
if (memchr(data, '>', len) == NULL) {
if (send_stat++ < 2) {
return Responder::ret::NEED_MORE_DATA;
}
ESP_LOGE(TAG, "Missed >");
return ret::FAIL;
}
auto written = dte->write(&buffer[0], data_to_send);
if (written != data_to_send) {
ESP_LOGE(TAG, "written %d (%d)...", written, len);
return ret::FAIL;
}
data_to_send = 0;
send_stat = 3;
}
return Responder::ret::IN_PROGRESS;
}
Responder::ret Responder::send(std::string_view response)
{
if (send_stat == 3) {
if (response.find("SEND OK") != std::string::npos) {
send_cmd("AT+QISEND=0,0\r");
send_stat++;
return ret::IN_PROGRESS;
} else if (response.find("SEND FAIL") != std::string::npos) {
ESP_LOGE(TAG, "Sending buffer full");
return ret::FAIL;
} else if (response.find("ERROR") != std::string::npos) {
ESP_LOGE(TAG, "Failed to sent");
return ret::FAIL;
}
} else if (send_stat == 4) {
constexpr std::string_view head = "+QISEND: ";
if (response.find(head) != std::string::npos) {
// Parsing +QISEND: <total_send_length>,<ackedbytes>,<unackedbytes>
size_t head_pos = response.find(head);
response = response.substr(head_pos + head.size());
int pos, property = 0;
int total = 0, ack = 0, unack = 0;
while ((pos = response.find(',')) != std::string::npos) {
auto next_comma = (char *)memchr(response.data(), ',', response.size());
// extract value
size_t value;
if (std::from_chars(response.data(), next_comma, value).ec == std::errc::invalid_argument) {
ESP_LOGE(TAG, "cannot convert");
return ret::FAIL;
}
switch (property++) {
case 0: total = value;
break;
case 1: ack = value;
break;
default:
return ret::FAIL;
}
response = response.substr(pos + 1);
}
if (std::from_chars(response.data(), response.data() + pos, unack).ec == std::errc::invalid_argument) {
return ret::FAIL;
}
if (ack < total) {
ESP_LOGD(TAG, "all sending data are not ack (missing %d bytes acked)", (total - ack));
if (total - ack > 64) {
ESP_LOGW(TAG, "Need a pause: missing %d bytes acked", (total - ack));
return ret::NEED_MORE_TIME;
}
}
send_stat = 0;
return ret::OK;
} else if (response.find("ERROR") != std::string::npos) {
ESP_LOGE(TAG, "Failed to check sending");
return ret::FAIL;
}
}
return Responder::ret::IN_PROGRESS;
}
Responder::ret Responder::connect(std::string_view response)
{
if (response.find("+QIOPEN: 0,0") != std::string::npos) {
ESP_LOGI(TAG, "Connected!");
return ret::OK;
}
if (response.find("ERROR") != std::string::npos) {
ESP_LOGE(TAG, "Failed to open");
return ret::FAIL;
}
return Responder::ret::IN_PROGRESS;
}
Responder::ret Responder::check_async_replies(status state, std::string_view &response)
{
ESP_LOGD(TAG, "response %.*s", static_cast<int>(response.size()), response.data());
if (response.find("+QIURC: \"recv\",0") != std::string::npos) {
uint64_t data_ready = 1;
write(data_ready_fd, &data_ready, sizeof(data_ready));
ESP_LOGD(TAG, "Got data on modem!");
} else if (response.find("+QIRD: ") != std::string::npos) {
static constexpr std::string_view head = "+QIRD: ";
size_t head_pos = response.find(head);
// Parsing +QIURC: <total_receive_length>,<have_read_length>,<unread_length>
response = response.substr(head_pos + head.size());
int next_cr = response.find('\r');
if (next_cr != std::string::npos) {
response = response.substr(next_cr - 2, next_cr);
if (response.find(",0") != std::string::npos) {
ESP_LOGV(TAG, "Receiving done");
} else {
uint64_t data_ready = 1;
write(data_ready_fd, &data_ready, sizeof(data_ready));
ESP_LOGD(TAG, "Got data on modem!");
}
}
} else if (response.find("+QIURC: \"closed\",0") != std::string::npos) {
return ret::FAIL;
}
if (state == status::SENDING) {
return send(response);
} else if (state == status::CONNECTING) {
return connect(response);
}
return ret::IN_PROGRESS;
}
Responder::ret Responder::process_data(status state, uint8_t *data, size_t len)
{
if (state == status::SENDING) {
return send(data, len);
}
if (state == status::RECEIVING) {
return recv(data, len);
}
return Responder::ret::IN_PROGRESS;
}
status Responder::pending()
{
send_cmd("AT+QISEND=0,0\r");
return status::SENDING;
}
} // sock_dce

View File

@ -0,0 +1,378 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <charconv>
#include <cstring>
#include <sys/socket.h>
#include "sock_commands.hpp"
#include "cxx_include/esp_modem_command_library_utils.hpp"
#include "sock_dce.hpp"
static const char *TAG = "sock_commands";
namespace sock_commands {
using namespace esp_modem;
command_result net_open(CommandableIf *term)
{
ESP_LOGV(TAG, "%s", __func__ );
std::string response;
auto ret = dce_commands::generic_get_string(term, "AT+NETOPEN?\r", response, 1000);
if (ret != command_result::OK) {
return ret;
}
ESP_LOGV(TAG, "%s", response.data() );
if (response.find("+NETOPEN: 1") != std::string::npos) {
ESP_LOGD(TAG, "Already there");
ret = command_result::OK;
} else if (response.find("+NETOPEN: 0") != std::string::npos) {
ESP_LOGD(TAG, "Need to setup");
ret = dce_commands::generic_command(term, "AT+NETOPEN\r", "+NETOPEN: 1", "+NETOPEN: 0", 10000);
} else {
return command_result::FAIL;
}
if (ret != command_result::OK) {
return ret;
}
return dce_commands::generic_command(term, "AT+CIPRXGET=1\r", "OK", "ERROR", 5000);
}
command_result net_close(CommandableIf *term)
{
ESP_LOGV(TAG, "%s", __func__ );
return dce_commands::generic_command(term, "AT+NETCLOSE\r", "+NETCLOSE:", "ERROR", 30000);
}
command_result tcp_open(CommandableIf *term, const std::string &host, int port, int timeout)
{
ESP_LOGV(TAG, "%s", __func__ );
auto ret = dce_commands::generic_command(term, "AT+CIPRXGET=1\r", "OK", "ERROR", 50000);
if (ret != command_result::OK) {
ESP_LOGE(TAG, "Setting Rx mode failed!");
return ret;
}
ESP_LOGV(TAG, "%s", __func__ );
std::string ip_open = R"(AT+CIPOPEN=0,"TCP",")" + host + "\"," + std::to_string(port) + "\r";
ret = dce_commands::generic_command(term, ip_open, "+CIPOPEN: 0,0", "ERROR", timeout);
if (ret != command_result::OK) {
ESP_LOGE(TAG, "%s Failed", __func__ );
return ret;
}
return command_result::OK;
}
command_result tcp_close(CommandableIf *term)
{
ESP_LOGV(TAG, "%s", __func__ );
return dce_commands::generic_command(term, "AT+CIPCLOSE=0\r", "+CIPCLOSE:", "ERROR", 10000);
}
command_result tcp_send(CommandableIf *term, uint8_t *data, size_t len)
{
ESP_LOGV(TAG, "%s", __func__ );
std::string send = "AT+CIPSEND=0," + std::to_string(len) + "\r";
auto ret = term->command(send, [&](uint8_t *data, size_t len) {
std::string_view response((char *)data, len);
ESP_LOGI(TAG, "CIPSEND response %.*s", static_cast<int>(response.size()), response.data());
if (response.find('>') != std::string::npos) {
return command_result::OK;
}
return command_result::TIMEOUT;
}, 50000, '>');
if (ret != command_result::OK) {
return ret;
}
ret = command_result::TIMEOUT;
ESP_LOGW(TAG, "Before setting...");
term->on_read([&ret](uint8_t *cmd_data, size_t cmd_len) {
std::string_view response((char *)cmd_data, cmd_len);
ESP_LOGW(TAG, "CIPSEND response %.*s", static_cast<int>(response.size()), response.data());
if (response.find("+CIPSEND:") != std::string::npos) {
ret = command_result::OK;
} else if (response.find("ERROR") != std::string::npos) {
ret = command_result::FAIL;
}
return ret;
});
ESP_LOGW(TAG, "Before writing...");
auto written = term->write(data, len);
if (written != len) {
ESP_LOGE(TAG, "written %d (%d)...", written, len);
return command_result::FAIL;
}
uint8_t ctrl_z = '\x1A';
term->write(&ctrl_z, 1);
int count = 0;
while (ret == command_result::TIMEOUT && count++ < 1000 ) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
term->on_read(nullptr);
return ret;
}
command_result tcp_recv(CommandableIf *term, uint8_t *data, size_t len, size_t &out_len)
{
ESP_LOGV(TAG, "%s", __func__ );
std::string out;
auto ret = dce_commands::generic_get_string(term, "AT+CIPRXGET=4,0\r", out);
if (ret != command_result::OK) {
return ret;
}
constexpr std::string_view pattern = "+CIPRXGET: 4,0,";
if (out.find(pattern) == std::string::npos) {
return command_result::FAIL;
}
size_t data_len;
if (std::from_chars(out.data() + pattern.size(), out.data() + out.size(), data_len).ec == std::errc::invalid_argument) {
return command_result::FAIL;
}
ESP_LOGD(TAG, "size=%d", data_len);
if (data_len == 0) {
out_len = data_len;
return command_result::OK;
}
return term->command("AT+CIPRXGET=2,0,100\r", [&](uint8_t *cmd_data, size_t cmd_len) {
char pattern[] = "+CIPRXGET: 2,0,";
ESP_LOG_BUFFER_HEXDUMP(TAG, cmd_data, cmd_len, ESP_LOG_DEBUG);
char *pos = strstr((char *)cmd_data, pattern);
if (pos == nullptr) {
return command_result::FAIL;
}
auto p1 = memchr(pos + sizeof(pattern) - 1, ',', 4);
if (p1 == nullptr) {
return command_result::FAIL;
}
*(char *)p1 = '\0';
size_t actual_len = atoi(pos + sizeof(pattern) - 1);
ESP_LOGD(TAG, "actual len=%d", actual_len);
pos = strchr((char *)p1 + 1, '\n');
if (pos == nullptr) {
ESP_LOGE(TAG, "not found");
return command_result::FAIL;
}
if (actual_len > len) {
ESP_LOGE(TAG, "TOO BIG");
return command_result::FAIL;
}
out_len = actual_len;
memcpy(data, pos + 1, actual_len);
pos = strstr((char *)pos + 1 + actual_len, "OK");
if (pos == nullptr) {
ESP_LOGE(TAG, "ok NOT FOUND");
return command_result::FAIL;
}
return command_result::OK;
}, 50000);
}
command_result get_ip(CommandableIf *term, std::string &ip)
{
std::string resp;
auto ret = dce_commands::generic_get_string(term, "AT+IPADDR\r", resp, 5000);
if (ret != command_result::OK) {
return ret;
}
ip = resp;
return command_result::OK;
}
command_result set_rx_mode(CommandableIf *term, int mode)
{
return dce_commands::generic_command(term, "AT+CIPRXGET=" + std::to_string(mode) + "\r", "OK", "ERROR", 5000);
}
} // sock_commands
namespace sock_dce {
void Responder::start_sending(size_t len)
{
data_to_send = len;
send_stat = 0;
send_cmd("AT+CIPSEND=0," + std::to_string(len) + "\r");
}
void Responder::start_receiving(size_t len)
{
send_cmd("AT+CIPRXGET=2,0," + std::to_string(len) + "\r");
}
bool Responder::start_connecting(std::string host, int port)
{
send_cmd(R"(AT+CIPOPEN=0,"TCP",")" + host + "\"," + std::to_string(port) + "\r");
return true;
}
Responder::ret Responder::recv(uint8_t *data, size_t len)
{
const int MIN_MESSAGE = 6;
size_t actual_len = 0;
auto *recv_data = (char *)data;
if (data_to_recv == 0) {
static constexpr std::string_view head = "+CIPRXGET: 2,0,";
auto head_pos = std::search(recv_data, recv_data + len, head.begin(), head.end());
if (head_pos == nullptr) {
return ret::FAIL;
}
if (head_pos - (char *)data > MIN_MESSAGE) {
// check for async replies before the Recv header
std::string_view response((char *)data, head_pos - (char *)data);
check_async_replies(status::RECEIVING, response);
}
auto next_comma = (char *)memchr(head_pos + head.size(), ',', MIN_MESSAGE);
if (next_comma == nullptr) {
return ret::FAIL;
}
if (std::from_chars(head_pos + head.size(), next_comma, actual_len).ec == std::errc::invalid_argument) {
ESP_LOGE(TAG, "cannot convert");
return ret::FAIL;
}
auto next_nl = (char *)memchr(next_comma, '\n', 8 /* total_len size (~4) + markers */);
if (next_nl == nullptr) {
ESP_LOGE(TAG, "not found");
return ret::FAIL;
}
if (actual_len > buffer_size) {
ESP_LOGE(TAG, "TOO BIG");
return ret::FAIL;
}
size_t total_len = 0;
if (std::from_chars(next_comma + 1, next_nl - 1, total_len).ec == std::errc::invalid_argument) {
ESP_LOGE(TAG, "cannot convert");
return ret::FAIL;
}
read_again = (total_len > 0);
recv_data = next_nl + 1;
auto first_data_len = len - (recv_data - (char *)data) /* minus size of the command marker */;
if (actual_len > first_data_len) {
::send(sock, recv_data, first_data_len, 0);
data_to_recv = actual_len - first_data_len;
return ret::NEED_MORE_DATA;
}
::send(sock, recv_data, actual_len, 0);
} else if (data_to_recv > len) { // continue sending
::send(sock, recv_data, len, 0);
data_to_recv -= len;
return ret::NEED_MORE_DATA;
} else if (data_to_recv <= len) { // last read -> looking for "OK" marker
::send(sock, recv_data, data_to_recv, 0);
actual_len = data_to_recv;
}
// "OK" after the data
char *last_pos = nullptr;
if (actual_len + 1 + 2 /* OK */ > len) {
last_pos = (char *)memchr(recv_data + 1 + actual_len, 'O', MIN_MESSAGE);
if (last_pos == nullptr || last_pos[1] != 'K') {
data_to_recv = 0;
return ret::FAIL;
}
}
if (last_pos != nullptr && (char *)data + len - last_pos - 2 > MIN_MESSAGE) {
// check for async replies after the Recv header
std::string_view response((char *)last_pos + 2 /* OK */, (char *)data + len - last_pos - 2);
check_async_replies(status::RECEIVING, response);
}
data_to_recv = 0;
if (read_again) {
uint64_t data_ready = 1;
write(data_ready_fd, &data_ready, sizeof(data_ready));
}
return ret::OK;
}
Responder::ret Responder::send(uint8_t *data, size_t len)
{
if (send_stat == 0) {
if (memchr(data, '>', len) == NULL) {
ESP_LOGE(TAG, "Missed >");
return ret::FAIL;
}
auto written = dte->write(&buffer[0], data_to_send);
if (written != data_to_send) {
ESP_LOGE(TAG, "written %d (%d)...", written, len);
return ret::FAIL;
}
data_to_send = 0;
uint8_t ctrl_z = '\x1A';
dte->write(&ctrl_z, 1);
send_stat++;
return ret::IN_PROGRESS;
}
return Responder::ret::IN_PROGRESS;
}
Responder::ret Responder::send(std::string_view response)
{
if (send_stat == 1) {
if (response.find("+CIPSEND:") != std::string::npos) {
send_stat = 0;
return ret::OK;
}
if (response.find("ERROR") != std::string::npos) {
ESP_LOGE(TAG, "Failed to sent");
send_stat = 0;
return ret::FAIL;
}
}
return Responder::ret::IN_PROGRESS;
}
Responder::ret Responder::connect(std::string_view response)
{
if (response.find("+CIPOPEN: 0,0") != std::string::npos) {
ESP_LOGI(TAG, "Connected!");
return ret::OK;
}
if (response.find("ERROR") != std::string::npos) {
ESP_LOGE(TAG, "Failed to open");
return ret::FAIL;
}
return Responder::ret::IN_PROGRESS;
}
Responder::ret Responder::check_async_replies(status state, std::string_view &response)
{
ESP_LOGD(TAG, "response %.*s", static_cast<int>(response.size()), response.data());
if (response.find("+CIPRXGET: 1") != std::string::npos) {
uint64_t data_ready = 1;
write(data_ready_fd, &data_ready, sizeof(data_ready));
ESP_LOGD(TAG, "Got data on modem!");
}
if (state == status::SENDING) {
return send(response);
} else if (state == status::CONNECTING) {
return connect(response);
}
return ret::IN_PROGRESS;
}
Responder::ret Responder::process_data(status state, uint8_t *data, size_t len)
{
if (state == status::SENDING) {
return send(data, len);
}
if (state == status::RECEIVING) {
return recv(data, len);
}
return Responder::ret::IN_PROGRESS;
}
status Responder::pending()
{
return status::PENDING;
}
} // sock_dce

View File

@ -0,0 +1,326 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <charconv>
#include <sys/socket.h>
#include "esp_vfs.h"
#include "esp_vfs_eventfd.h"
#include "sock_dce.hpp"
namespace sock_dce {
constexpr auto const *TAG = "sock_dce";
bool DCE::perform_sock()
{
if (listen_sock == -1) {
ESP_LOGE(TAG, "Listening socket not ready");
close_sock();
return false;
}
if (sock == -1) { // no active socket, need to accept one first
return accept_sock();
}
// we have a socket, let's check the status
struct timeval tv = {
.tv_sec = 0,
.tv_usec = 500000,
};
if (state == status::PENDING) {
vTaskDelay(pdMS_TO_TICKS(500));
state = at.pending();
return true;
}
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
FD_SET(data_ready_fd, &fdset);
int s = select(std::max(sock, data_ready_fd) + 1, &fdset, nullptr, nullptr, &tv);
if (s == 0) {
ESP_LOGV(TAG, "perform select timeout...");
return true;
} else if (s < 0) {
ESP_LOGE(TAG, "select error %d", errno);
close_sock();
return false;
}
if (FD_ISSET(sock, &fdset) && !sock_to_at()) {
return false;
}
if (FD_ISSET(data_ready_fd, &fdset) && !at_to_sock()) {
return false;
}
return true;
}
void DCE::perform_at(uint8_t *data, size_t len)
{
ESP_LOG_BUFFER_HEXDUMP(TAG, data, len, ESP_LOG_VERBOSE);
switch (at.process_data(state, data, len)) {
case Responder::ret::OK:
state = status::IDLE;
signal.set(IDLE);
return;
case Responder::ret::FAIL:
state = status::FAILED;
signal.set(IDLE);
return;
case Responder::ret::NEED_MORE_DATA:
return;
case Responder::ret::IN_PROGRESS:
break;
case Responder::ret::NEED_MORE_TIME:
state = status::PENDING;
return;
}
std::string_view response((char *)data, len);
switch (at.check_async_replies(state, response)) {
case Responder::ret::OK:
state = status::IDLE;
signal.set(IDLE);
return;
case Responder::ret::FAIL:
state = status::FAILED;
signal.set(IDLE);
return;
case Responder::ret::NEED_MORE_TIME:
state = status::PENDING;
return;
case Responder::ret::NEED_MORE_DATA:
case Responder::ret::IN_PROGRESS:
break;
}
}
void DCE::close_sock()
{
if (sock > 0) {
close(sock);
sock = -1;
}
dte->on_read(nullptr);
const int retries = 5;
int i = 0;
while (net_close() != esp_modem::command_result::OK) {
if (i++ > retries) {
ESP_LOGE(TAG, "Failed to close network");
return;
}
esp_modem::Task::Delay(1000);
}
}
bool DCE::at_to_sock()
{
uint64_t data;
read(data_ready_fd, &data, sizeof(data));
ESP_LOGD(TAG, "select read: modem data available %x", data);
if (!signal.wait(IDLE, 1000)) {
ESP_LOGE(TAG, "Failed to get idle");
close_sock();
return false;
}
if (state != status::IDLE) {
ESP_LOGE(TAG, "Unexpected state %d", state);
close_sock();
return false;
}
state = status::RECEIVING;
at.start_receiving(at.get_buf_len());
return true;
}
bool DCE::sock_to_at()
{
ESP_LOGD(TAG, "socket read: data available");
if (!signal.wait(IDLE, 1000)) {
ESP_LOGE(TAG, "Failed to get idle");
close_sock();
return false;
}
if (state != status::IDLE) {
ESP_LOGE(TAG, "Unexpected state %d", state);
close_sock();
return false;
}
state = status::SENDING;
int len = ::recv(sock, at.get_buf(), at.get_buf_len(), 0);
if (len < 0) {
ESP_LOGE(TAG, "read error %d", errno);
close_sock();
return false;
} else if (len == 0) {
ESP_LOGE(TAG, "EOF %d", errno);
close_sock();
return false;
}
ESP_LOG_BUFFER_HEXDUMP(TAG, at.get_buf(), len, ESP_LOG_VERBOSE);
at.start_sending(len);
return true;
}
bool DCE::accept_sock()
{
struct timeval tv = {
.tv_sec = 0,
.tv_usec = 500000,
};
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(listen_sock, &fdset);
int s = select(listen_sock + 1, &fdset, nullptr, nullptr, &tv);
if (s > 0 && FD_ISSET(listen_sock, &fdset)) {
struct sockaddr_in source_addr = {};
socklen_t addr_len = sizeof(source_addr);
sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
if (sock < 0) {
ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno);
return false;
}
ESP_LOGD(TAG, "Socket accepted!");
FD_ZERO(&fdset);
return true;
} else if (s == 0) {
return true;
}
return false;
}
void DCE::init_sock(int port)
{
esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
esp_vfs_eventfd_register(&config);
data_ready_fd = eventfd(0, EFD_SUPPORT_ISR);
assert(data_ready_fd > 0);
listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (listen_sock < 0) {
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
return;
}
int opt = 1;
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
ESP_LOGI(TAG, "Socket created");
struct sockaddr_in addr = { };
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
// inet_aton("127.0.0.1", &addr.sin_addr);
int err = bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr));
if (err != 0) {
ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno);
return;
}
ESP_LOGI(TAG, "Socket bound, port %d", 1883);
err = listen(listen_sock, 1);
if (err != 0) {
ESP_LOGE(TAG, "Error occurred during listen: errno %d", errno);
return;
}
}
bool DCE::start(std::string host, int port)
{
dte->on_read(nullptr);
tcp_close();
dte->on_read([this](uint8_t *data, size_t len) {
this->perform_at(data, len);
return esp_modem::command_result::TIMEOUT;
});
if (!at.start_connecting(host, port)) {
ESP_LOGE(TAG, "Unable to start connecting");
dte->on_read(nullptr);
return false;
}
state = status::CONNECTING;
return true;
}
bool DCE::init_network()
{
dte->on_read(nullptr);
const int retries = 5;
int i = 0;
while (sync() != esp_modem::command_result::OK) {
if (i++ > retries) {
ESP_LOGE(TAG, "Failed to sync up");
return false;
}
esp_modem::Task::Delay(1000);
}
ESP_LOGD(TAG, "Modem in sync");
i = 0;
while (setup_data_mode() != true) {
if (i++ > retries) {
ESP_LOGE(TAG, "Failed to setup pdp/data");
return false;
}
esp_modem::Task::Delay(1000);
}
ESP_LOGD(TAG, "PDP configured");
i = 0;
while (net_open() != esp_modem::command_result::OK) {
if (i++ > retries) {
ESP_LOGE(TAG, "Failed to open network");
return false;
}
net_close();
esp_modem::Task::Delay(1000);
}
ESP_LOGD(TAG, "Network opened");
i = 0;
std::string ip_addr;
while (get_ip(ip_addr) != esp_modem::command_result::OK) {
if (i++ > retries) {
ESP_LOGE(TAG, "Failed obtain an IP address");
return false;
}
esp_modem::Task::Delay(5000);
}
ESP_LOGI(TAG, "Got IP %s", ip_addr.c_str());
return true;
}
class Factory: public ::esp_modem::dce_factory::Factory {
public:
static std::unique_ptr<DCE> create(const esp_modem::dce_config *config, std::shared_ptr<esp_modem::DTE> dte)
{
return esp_modem::dce_factory::Factory::build_module_T<DCE, std::unique_ptr<DCE>>(config, std::move(dte));
}
};
std::unique_ptr<DCE> create(const esp_modem::dce_config *config, std::shared_ptr<esp_modem::DTE> dte)
{
return Factory::create(config, std::move(dte));
}
// Helper macros to handle multiple arguments of declared API
#define ARGS0
#define ARGS1 , p1
#define ARGS2 , p1 , p2
#define ARGS3 , p1 , p2 , p3
#define EXPAND_ARGS(x) ARGS ## x
#define ARGS(x) EXPAND_ARGS(x)
//
// Repeat all declarations and forward to the AT commands defined in ::sock_commands namespace
//
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, arg_nr, ...) \
esp_modem::return_type DCE::name(__VA_ARGS__) { return sock_commands::name(dte.get() ARGS(arg_nr) ); }
DECLARE_SOCK_COMMANDS(return_type name(...) )
#undef ESP_MODEM_DECLARE_DCE_COMMAND
} // namespace sock_dce

View File

@ -0,0 +1,108 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_modem_config.h"
#include "cxx_include/esp_modem_api.hpp"
#include <cxx_include/esp_modem_dce_factory.hpp>
#include "socket_commands.inc"
#include "sock_commands.hpp"
#pragma once
namespace sock_dce {
enum class status {
IDLE,
CONNECTING,
SENDING,
RECEIVING,
FAILED,
PENDING
};
class Responder {
public:
enum class ret {
OK, FAIL, IN_PROGRESS, NEED_MORE_DATA, NEED_MORE_TIME
};
Responder(int &s, int &ready_fd, std::shared_ptr<esp_modem::DTE> &dte_arg):
sock(s), data_ready_fd(ready_fd), dte(dte_arg) {}
ret process_data(status state, uint8_t *data, size_t len);
ret check_async_replies(status state, std::string_view &response);
void start_sending(size_t len);
void start_receiving(size_t len);
bool start_connecting(std::string host, int port);
status pending();
uint8_t *get_buf()
{
return &buffer[0];
}
size_t get_buf_len()
{
return buffer_size;
}
private:
static constexpr size_t buffer_size = 512;
ret recv(uint8_t *data, size_t len);
ret send(uint8_t *data, size_t len);
ret send(std::string_view response);
ret connect(std::string_view response);
void send_cmd(std::string_view command)
{
dte->write((uint8_t *) command.begin(), command.size());
}
std::array<uint8_t, buffer_size> buffer;
size_t data_to_recv = 0;
bool read_again = false;
int &sock;
int &data_ready_fd;
int send_stat = 0;
size_t data_to_send = 0;
std::shared_ptr<esp_modem::DTE> &dte;
};
class DCE : public ::esp_modem::GenericModule {
using esp_modem::GenericModule::GenericModule;
public:
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \
esp_modem::return_type name(__VA_ARGS__);
DECLARE_SOCK_COMMANDS(declare name(Commandable *p, ...);)
#undef ESP_MODEM_DECLARE_DCE_COMMAND
bool init_network();
bool start(std::string host, int port);
void init_sock(int port);
bool perform_sock();
private:
esp_modem::SignalGroup signal;
void close_sock();
bool accept_sock();
bool sock_to_at();
bool at_to_sock();
void perform_at(uint8_t *data, size_t len);
status state{status::IDLE};
static constexpr uint8_t IDLE = 1;
Responder at{sock, data_ready_fd, dte};
int sock {-1};
int listen_sock {-1};
int data_ready_fd {-1};
};
std::unique_ptr<DCE> create(const esp_modem::dce_config *config, std::shared_ptr<esp_modem::DTE> dte);
}

View File

@ -0,0 +1,58 @@
// 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 "generate/esp_modem_command_declare_helper.inc"
#define DECLARE_SOCK_COMMANDS(...) \
/**
* @brief Opens network in AT command mode
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(net_open, command_result, 0) \
\
/**
* @brief Closes network in AT command mode
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(net_close, command_result, 0) \
\
/**
* @brief Opens a TCP connection
* @param[in] host Host name or IP address to connect to
* @param[in] port Port number
* @param[in] timeout Connection timeout
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(tcp_open, command_result, 3, STRING_IN(p1, host), INT_IN(p2, port), INT_IN(p3, timeout)) \
\
/**
* @brief Closes opened TCP socket
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(tcp_close, command_result, 0) \
\
/**
* @brief Gets modem IP address
* @param[out] addr String representation of modem's IP
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(get_ip, command_result, 1, STRING_OUT(p1, addr)) \
\
/**
* @brief Sets Rx mode
* @param[in] mode 0=auto, 1=manual
* @return OK, FAIL or TIMEOUT
*/ \
ESP_MODEM_DECLARE_DCE_COMMAND(set_rx_mode, command_result, 1, INT_IN(p1, mode))

View File

@ -15,12 +15,12 @@ menu "Example Configuration"
endchoice
choice EXAMPLE_MODEM_DEVICE
depends on EXAMPLE_SERIAL_CONFIG_UART
prompt "Choose supported modem device (DCE)"
default EXAMPLE_MODEM_DEVICE_BG96
help
Select modem device connected to the ESP DTE.
config EXAMPLE_MODEM_DEVICE_SIM800
depends on EXAMPLE_SERIAL_CONFIG_UART
bool "SIM800"
help
SIMCom SIM800L is a GSM/GPRS module.
@ -30,10 +30,12 @@ menu "Example Configuration"
help
Quectel BG96 is a series of LTE Cat M1/Cat NB1/EGPRS module.
config EXAMPLE_MODEM_DEVICE_SIM7000
depends on EXAMPLE_SERIAL_CONFIG_UART
bool "SIM7000"
help
SIM7000 is a Multi-Band LTE-FDD and GSM/GPRS/EDGE module.
config EXAMPLE_MODEM_DEVICE_SIM7070
depends on EXAMPLE_SERIAL_CONFIG_UART
bool "SIM7070"
help
SIM7070 is Multi-Band CAT M and NB IoT module.
@ -41,6 +43,11 @@ menu "Example Configuration"
bool "SIM7600"
help
SIM7600 is a Multi-Band LTE-TDD/LTE-FDD/HSPA+ and GSM/GPRS/EDGE module.
config EXAMPLE_MODEM_DEVICE_A7670
depends on EXAMPLE_SERIAL_CONFIG_USB
bool "A7670"
help
A7670X is Multi-Band LTE-FDD/LTE-TDD/GSM/GPRS/EDGE module.
endchoice
config EXAMPLE_MODEM_PPP_APN

View File

@ -3,10 +3,10 @@ dependencies:
## Required IDF version
idf: ">=4.1.0"
espressif/esp_modem:
version: "^0.1.23"
version: "^1.0.0"
override_path: "../../../"
espressif/esp_modem_usb_dte:
version: "^1.0.0"
version: "^1.1.0"
rules:
- if: "idf_version >=4.4"
- if: "target in [esp32s2, esp32s3]"

View File

@ -208,14 +208,28 @@ void app_main(void)
#elif defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
while (1) {
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
ESP_LOGI(TAG, "Initializing esp_modem for the BG96 module...");
struct esp_modem_usb_term_config usb_config = ESP_MODEM_DEFAULT_USB_CONFIG(0x2C7C, 0x0296, 2); // VID, PID and interface num of BG96 modem
struct esp_modem_usb_term_config usb_config = ESP_MODEM_BG96_USB_CONFIG();
esp_modem_dce_device_t usb_dev_type = ESP_MODEM_DCE_BG96;
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
ESP_LOGI(TAG, "Initializing esp_modem for the SIM7600 module...");
struct esp_modem_usb_term_config usb_config = ESP_MODEM_SIM7600_USB_CONFIG();
esp_modem_dce_device_t usb_dev_type = ESP_MODEM_DCE_SIM7600;
#elif CONFIG_EXAMPLE_MODEM_DEVICE_A7670 == 1
ESP_LOGI(TAG, "Initializing esp_modem for the A7670 module...");
struct esp_modem_usb_term_config usb_config = ESP_MODEM_A7670_USB_CONFIG();
esp_modem_dce_device_t usb_dev_type = ESP_MODEM_DCE_SIM7600;
#else
#error USB modem not selected
#endif
const esp_modem_dte_config_t dte_usb_config = ESP_MODEM_DTE_DEFAULT_USB_CONFIG(usb_config);
ESP_LOGI(TAG, "Waiting for USB device connection...");
esp_modem_dce_t *dce = esp_modem_new_dev_usb(ESP_MODEM_DCE_BG96, &dte_usb_config, &dce_config, esp_netif);
esp_modem_dce_t *dce = esp_modem_new_dev_usb(usb_dev_type, &dte_usb_config, &dce_config, esp_netif);
assert(dce);
esp_modem_set_error_cb(dce, usb_terminal_error_handler);
vTaskDelay(pdMS_TO_TICKS(1000)); // Although the DTE should be ready after USB enumeration, sometimes it fails to respond without this delay
ESP_LOGI(TAG, "Modem connected, waiting 10 seconds for boot...");
vTaskDelay(pdMS_TO_TICKS(10000)); // Give DTE some time to boot
#else
#error Invalid serial connection to modem.

View File

@ -1,3 +1,4 @@
CONFIG_IDF_TARGET="esp32c3"
# Override some defaults to enable PPP
CONFIG_LWIP_PPP_SUPPORT=y
CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y

View File

@ -0,0 +1,2 @@
CONFIG_IDF_TARGET="esp32s2"
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y

View File

@ -0,0 +1,2 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y

View File

@ -1,6 +1,7 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.8)
set(CMAKE_CXX_STANDARD 17)
set(EXTRA_COMPONENT_DIRS "../..")

View File

@ -1,4 +1,4 @@
version: "0.1.27"
version: "1.0.0"
description: esp modem
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_modem
dependencies:

View File

@ -22,6 +22,19 @@ namespace dce_commands {
* @{
*/
/**
* @brief Generic AT command to be send with pass and fail phrases
*
* @param t Commandable object (anything that can accept commands)
* @param command Command to be sent do the commandable object
* @param pass_phrase String to be present in the reply to pass this command
* @param fail_phrase String to be present in the reply to fail this command
* @param timeout_ms Timeout in ms
*/
command_result generic_command(CommandableIf *t, const std::string &command,
const std::string &pass_phrase,
const std::string &fail_phrase, uint32_t timeout_ms);
/**
* @brief Declaration of all commands is generated from esp_modem_command_declare.inc
*/

View File

@ -69,6 +69,10 @@ public:
ESP_MODEM_THROW_IF_FALSE(netif != nullptr, "Null netif");
}
explicit Creator(std::shared_ptr<DTE> dte): dte(std::move(dte)), device(nullptr), netif(nullptr)
{
}
~Creator()
{
if (device != nullptr) {

View File

@ -29,6 +29,13 @@ class CMux;
* @{
*/
struct DTE_Command {
DTE_Command(const std::string &cmd): data((uint8_t *)cmd.c_str()), len(cmd.length()) {}
uint8_t *data;
size_t len;
};
/**
* DTE (Data Terminal Equipment) class
*/
@ -39,9 +46,12 @@ public:
* @brief Creates a DTE instance from the terminal
* @param config DTE config structure
* @param t unique-ptr to Terminal
* @param s unique-ptr to secondary Terminal
*/
explicit DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> t);
explicit DTE(std::unique_ptr<Terminal> t);
explicit DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s);
explicit DTE(std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s);
~DTE() = default;
@ -51,7 +61,9 @@ public:
* @param len Data len to write
* @return number of bytes written
*/
int write(uint8_t *data, size_t len);
int write(uint8_t *data, size_t len) override;
int write(DTE_Command command);
/**
* @brief Reading from the underlying terminal
@ -67,6 +79,8 @@ public:
*/
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f);
void on_read(got_line_cb on_data) override;
/**
* @brief Sets DTE error callback
* @param f Function to be called on DTE error

View File

@ -27,8 +27,9 @@ namespace esp_modem {
*/
enum class modem_mode {
UNDEF,
COMMAND_MODE, /*!< Command mode -- the modem is supposed to send AT commands in this mode */
COMMAND_MODE, /*!< Command mode -- the modem is supposed to send AT commands in this mode */
DATA_MODE, /*!< Data mode -- the modem communicates with network interface on PPP protocol */
DUAL_MODE, /*!< Dual mode -- the modem has two real terminals. Data and commands work at the same time */
CMUX_MODE, /*!< CMUX (Multiplex mode) -- Simplified CMUX mode, which creates two virtual terminals,
* assigning one solely to command interface and the other to the data mode */
CMUX_MANUAL_MODE, /*!< Enter CMUX mode manually -- just creates two virtual terminals */
@ -79,6 +80,9 @@ public:
*/
virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0;
virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) = 0;
virtual int write(uint8_t *data, size_t len) = 0;
virtual void on_read(got_line_cb on_data) = 0;
};
/**

View File

@ -84,6 +84,11 @@ struct esp_modem_dte_config {
};
};
#if ESP_IDF_VERSION_MAJOR >= 5
#define ESP_MODEM_DEFAULT_UART_CLK UART_SCLK_DEFAULT
#else
#define ESP_MODEM_DEFAULT_UART_CLK UART_SCLK_APB
#endif
/**
* @brief ESP Modem DTE Default Configuration
@ -92,15 +97,15 @@ struct esp_modem_dte_config {
#define ESP_MODEM_DTE_DEFAULT_CONFIG() \
{ \
.dte_buffer_size = 512, \
.task_stack_size = 4096, \
.task_priority = 5, \
.task_stack_size = 4096, \
.task_priority = 5, \
.uart_config = { \
.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,\
.source_clk = UART_SCLK_APB, \
.source_clk = ESP_MODEM_DEFAULT_UART_CLK, \
.baud_rate = 115200, \
.tx_io_num = 25, \
.rx_io_num = 26, \

View File

@ -1,4 +1,4 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
// 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.
@ -11,36 +11,11 @@
// 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
#ifndef _ESP_MODEM_COMMAND_DECLARE_INC_
#define _ESP_MODEM_COMMAND_DECLARE_INC_
#include "generate/esp_modem_command_declare_helper.inc"
// Parameters
// * handle different parameters for C++ and C API
// * make parameter unique names, so they could be easily referenced and forwarded
#define _ARG(param, name) param
#define INT_IN(param, name) int _ARG(param, name)
#ifdef __cplusplus
#include <string>
#define STRING_IN(param, name) const std::string& _ARG(param, name)
#define STRING_OUT(param, name) std::string& _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 INTEGER_LIST_IN(param, name) const int* _ARG(param, name)
#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 INTEGER_LIST_IN(param, name) const int* _ARG(param, name)
#define STRUCT_OUT(struct_name, p1) esp_modem_ ## struct_name ## _t* p1
#endif
#define DECLARE_ALL_COMMAND_APIS(...) \
/**
* @brief Sends the initial AT sequence to sync up with the device
@ -331,5 +306,3 @@ public:
#endif
#endif
#endif // _ESP_MODEM_COMMAND_DECLARE_INC_

View File

@ -0,0 +1,26 @@
// Parameters
// * handle different parameters for C++ and C API
// * make parameter unique names, so they could be easily referenced and forwarded
#define _ARG(param, name) param
#define INT_IN(param, name) int _ARG(param, name)
#ifdef __cplusplus
#include <string>
#define STRING_IN(param, name) const std::string& _ARG(param, name)
#define STRING_OUT(param, name) std::string& _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 INTEGER_LIST_IN(param, name) const int* _ARG(param, name)
#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 INTEGER_LIST_IN(param, name) const int* _ARG(param, name)
#define STRUCT_OUT(struct_name, p1) esp_modem_ ## struct_name ## _t* p1
#endif

View File

@ -88,6 +88,7 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
{
switch (m) {
case modem_mode::UNDEF:
case modem_mode::DUAL_MODE: // Only DTE can be in Dual mode
break;
case modem_mode::COMMAND_MODE:
if (mode == modem_mode::COMMAND_MODE || mode >= modem_mode::CMUX_MANUAL_MODE) {

View File

@ -24,6 +24,16 @@ DTE::DTE(std::unique_ptr<Terminal> terminal):
cmux_term(nullptr), primary_term(std::move(terminal)), secondary_term(primary_term),
mode(modem_mode::UNDEF) {}
DTE::DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s):
buffer(config->dte_buffer_size),
cmux_term(nullptr), primary_term(std::move(t)), secondary_term(std::move(s)),
mode(modem_mode::DUAL_MODE) {}
DTE::DTE(std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s):
buffer(dte_default_buffer_size),
cmux_term(nullptr), primary_term(std::move(t)), secondary_term(std::move(s)),
mode(modem_mode::DUAL_MODE) {}
command_result DTE::command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator)
{
Scoped<Lock> l(internal_lock);
@ -104,9 +114,9 @@ bool DTE::set_mode(modem_mode m)
return false;
}
}
// transitions (COMMAND|CMUX|UNDEF) -> DATA
// transitions (COMMAND|DUAL|CMUX|UNDEF) -> DATA
if (m == modem_mode::DATA_MODE) {
if (mode == modem_mode::CMUX_MODE || mode == modem_mode::CMUX_MANUAL_MODE) {
if (mode == modem_mode::CMUX_MODE || mode == modem_mode::CMUX_MANUAL_MODE || mode == modem_mode::DUAL_MODE) {
// mode stays the same, but need to swap terminals (as command has been switched)
secondary_term.swap(primary_term);
} else {
@ -114,7 +124,7 @@ bool DTE::set_mode(modem_mode m)
}
return true;
}
// transitions (DATA|CMUX|UNDEF) -> COMMAND
// transitions (DATA|DUAL|CMUX|UNDEF) -> COMMAND
if (m == modem_mode::COMMAND_MODE) {
if (mode == modem_mode::CMUX_MODE) {
if (exit_cmux()) {
@ -123,7 +133,7 @@ bool DTE::set_mode(modem_mode m)
}
mode = modem_mode::UNDEF;
return false;
} if (mode == modem_mode::CMUX_MANUAL_MODE) {
} if (mode == modem_mode::CMUX_MANUAL_MODE || mode == modem_mode::DUAL_MODE) {
return true;
} else {
mode = m;
@ -192,6 +202,34 @@ int DTE::write(uint8_t *data, size_t len)
return secondary_term->write(data, len);
}
int DTE::write(DTE_Command command)
{
return primary_term->write(command.data, command.len);
}
void DTE::on_read(got_line_cb on_read_cb)
{
if (on_read_cb == nullptr) {
primary_term->set_read_cb(nullptr);
internal_lock.unlock();
return;
}
internal_lock.lock();
primary_term->set_read_cb([this, on_read_cb](uint8_t *data, size_t len) {
if (!data) {
data = buffer.get();
len = primary_term->read(data, buffer.size);
}
auto res = on_read_cb(data, len);
if (res == command_result::OK || res == command_result::FAIL) {
primary_term->set_read_cb(nullptr);
internal_lock.unlock();
return true;
}
return false;
});
}
/**
* Implemented here to keep all headers C++11 compliant
*/

View File

@ -0,0 +1,7 @@
# Changelog
## [0.1.0](https://github.com/espressif/esp-protocols/commits/1407dfc)
### Updated
- Adds esp_mqtt_cxx component ([1407dfc](https://github.com/espressif/esp-protocols/commit/1407dfc))

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@ -0,0 +1,13 @@
# esp_mqtt_cxx
[![Component Registry](https://components.espressif.com/components/espressif/esp_mqtt_cxx/badge.svg)](https://components.espressif.com/components/espressif/esp_mqtt_cxx)
The ESP MQTT client is a wrapper over the esp_mqtt client with the goal of providing a higher level API.
## Examples
Get started with [examples](https://github.com/espressif/esp-protocols/tree/master/components/esp_mqtt_cxx/examples)
## Documentation
* View the full [html documentation](https://docs.espressif.com/projects/esp-protocols/docs/latest/esp_mqtt_cxx/index.html)

View File

@ -92,8 +92,35 @@ void config_client_credentials(esp_mqtt_client_config_t &mqtt_client_cfg, Client
{
mqtt_client_cfg.credentials.authentication.password = password.data.c_str();
},
[](ClientCertificate const & certificate) {},
[](SecureElement const & enable_secure_element) {},
[&mqtt_client_cfg](ClientCertificate const & certificate)
{
std::visit(overloaded{
[&mqtt_client_cfg](PEM const & pem)
{
mqtt_client_cfg.credentials.authentication.certificate = pem.data;
}, [&mqtt_client_cfg](DER const & der)
{
mqtt_client_cfg.credentials.authentication.certificate = der.data;
mqtt_client_cfg.credentials.authentication.certificate_len = der.len;
}}, certificate.certificate);
std::visit(overloaded{
[&mqtt_client_cfg](PEM const & pem)
{
mqtt_client_cfg.credentials.authentication.key = pem.data;
}, [&mqtt_client_cfg](DER const & der)
{
mqtt_client_cfg.credentials.authentication.key = der.data;
mqtt_client_cfg.credentials.authentication.key_len = der.len;
}}, certificate.key);
if (certificate.key_password.has_value()) {
mqtt_client_cfg.credentials.authentication.key_password = certificate.key_password.value().data.c_str();
mqtt_client_cfg.credentials.authentication.key_password_len = static_cast<int>(certificate.key_password.value().data.size());
}
},
[&mqtt_client_cfg](SecureElement const & enable_secure_element)
{
mqtt_client_cfg.credentials.authentication.use_secure_element = true;
},
[]([[maybe_unused ]]auto & unknown)
{
static_assert(always_false<decltype(unknown)>, "Missing type handler for variant handler");

View File

@ -0,0 +1,107 @@
# Changelog
## [1.0.0](https://github.com/espressif/esp-protocols/commits/996fef7)
### Updated
- esp_websocket_client: Updated version to 1.0.0 Updated tests to run agains release-v5.0 ([996fef7](https://github.com/espressif/esp-protocols/commit/996fef7))
- esp_websocket_client: * Error handling improved to show status code from server * Added new API `esp_websocket_client_set_headers` * Dispatches 'WEBSOCKET_EVENT_BEFORE_CONNECT' event before tcp connection ([d047ff5](https://github.com/espressif/esp-protocols/commit/d047ff5))
- unite all tags under common structure py test: update tags under common structure ([c6db3ea](https://github.com/espressif/esp-protocols/commit/c6db3ea))
- websocket: Support HTTP basic authorization ([1b13448](https://github.com/espressif/esp-protocols/commit/1b13448))
- Add task_name config option ([1d68884](https://github.com/espressif/esp-protocols/commit/1d68884))
- Add websocket error messages ([d68624e](https://github.com/espressif/esp-protocols/commit/d68624e))
- websocket: Added new API `esp_websocket_client_destroy_on_exit` ([f9b4790](https://github.com/espressif/esp-protocols/commit/f9b4790))
- Added badges with version of components to the respective README files ([e4c8a59](https://github.com/espressif/esp-protocols/commit/e4c8a59))
## [0.0.4](https://github.com/espressif/esp-protocols/commits/3330b96)
### Updated
- websocket: make `esp_websocket_client_send_with_opcode` a public API ([3330b96](https://github.com/espressif/esp-protocols/commit/3330b96))
- websocket: updated example to use local websocket echo server ([55dc564](https://github.com/espressif/esp-protocols/commit/55dc564))
- CI: Created a common requirements.txt ([23a537b](https://github.com/espressif/esp-protocols/commit/23a537b))
- Examples: using pytest.ini from top level directory ([aee016d](https://github.com/espressif/esp-protocols/commit/aee016d))
- CI: fixing the files to be complient with pre-commit hooks ([945bd17](https://github.com/espressif/esp-protocols/commit/945bd17))
- websocket: updated example to show json data transfer ([3456781](https://github.com/espressif/esp-protocols/commit/3456781))
## [0.0.3](https://github.com/espressif/esp-protocols/commits/5c245db)
### Updated
- esp_websocket_client: Upgraded version to 0.0.3 ([5c245db](https://github.com/espressif/esp-protocols/commit/5c245db))
- CI: Fix build issues ([6e4e4fa](https://github.com/espressif/esp-protocols/commit/6e4e4fa))
## [0.0.2](https://github.com/espressif/esp-protocols/commits/57afa38)
### Features
- Optimize memory size for websocket client init ([4cefcd3](https://github.com/espressif/esp-protocols/commit/4cefcd3))
- allow users to attach CA bundle ([d56b5d9](https://github.com/espressif/esp-protocols/commit/d56b5d9))
### Bug Fixes
- Docs to refer esp-protocols ([91a177e](https://github.com/espressif/esp-protocols/commit/91a177e))
### Updated
- Bump asio/mdns/esp_websocket_client versions ([57afa38](https://github.com/espressif/esp-protocols/commit/57afa38))
- ignore format warnings ([d66f9dc](https://github.com/espressif/esp-protocols/commit/d66f9dc))
- Minor fixes here and there ([8fe2a3a](https://github.com/espressif/esp-protocols/commit/8fe2a3a))
- CI: Added CI example run job ([76298ff](https://github.com/espressif/esp-protocols/commit/76298ff))
- Implement websocket client connect error ([9e37f53](https://github.com/espressif/esp-protocols/commit/9e37f53))
- Add methods to allow get/set of websocket client ping interval ([e55f54b](https://github.com/espressif/esp-protocols/commit/e55f54b))
- esp_websocket_client: Expose frame fin flag in websocket event ([b72a9ae](https://github.com/espressif/esp-protocols/commit/b72a9ae))
## [0.0.1](https://github.com/espressif/esp-protocols/commits/80c3cf0)
### Updated
- websocket: Initial version based on IDF 5.0 ([80c3cf0](https://github.com/espressif/esp-protocols/commit/80c3cf0))
- freertos: Remove legacy data types ([b3c777a](https://github.com/espressif/esp-protocols/commit/b3c777a), [IDF@57fd78f](https://github.com/espressif/esp-idf/commit/57fd78f5baf93a368a82cf4b2e00ca17ffc09115))
- websocket: Added configs `reconnect_timeout_ms` and `network_timeout_ms` ([8ce791e](https://github.com/espressif/esp-protocols/commit/8ce791e), [IDF#8263](https://github.com/espressif/esp-idf/issues/8263), [IDF@6c26d65](https://github.com/espressif/esp-idf/commit/6c26d6520311f83c2ebe852a487c36185a429a69))
- Add http_parser (new component) dependency ([bece6e7](https://github.com/espressif/esp-protocols/commit/bece6e7), [IDF@8e94cf2](https://github.com/espressif/esp-idf/commit/8e94cf2bb1498e94045e73e649f1046111fc6f9f))
- websocket: removed deprecated API "esp_websocket_client_send" ([46bd32d](https://github.com/espressif/esp-protocols/commit/46bd32d), [IDF@7f6ab93](https://github.com/espressif/esp-idf/commit/7f6ab93f7e52bddaf4c030d7337ea5574f33381d))
- refactor (test_utils)!: separate file for memory check functions ([525c70c](https://github.com/espressif/esp-protocols/commit/525c70c), [IDF@16514f9](https://github.com/espressif/esp-idf/commit/16514f93f06cd833306459d615458536a9f2e5cd))
- Build & config: Remove leftover files from the unsupported "make" build system ([19c0455](https://github.com/espressif/esp-protocols/commit/19c0455), [IDF@766aa57](https://github.com/espressif/esp-idf/commit/766aa5708443099f3f033b739cda0e1de101cca6))
- transport: Add CONFI_WS_TRANSPORT for optimize the code size ([9118e0f](https://github.com/espressif/esp-protocols/commit/9118e0f), [IDF@8b02c90](https://github.com/espressif/esp-idf/commit/8b02c9026af32352c8c4ed23025fb42182db6cae))
- ws_client: Fix const correctness in the API config structure ([fbdbd55](https://github.com/espressif/esp-protocols/commit/fbdbd55), [IDF@70b1247](https://github.com/espressif/esp-idf/commit/70b1247a47f4583fccd8a91bf6cc532e5741e632))
- components: Remove repeated keep alive function by ssl layer function ([de7cd72](https://github.com/espressif/esp-protocols/commit/de7cd72), [IDF@c79a907](https://github.com/espressif/esp-idf/commit/c79a907e4fef0c54175ad5659bc0df45a40745c9))
- components: Support bind socket to specified interface in esp_http_client and esp_websocket_client component ([4a608ec](https://github.com/espressif/esp-protocols/commit/4a608ec), [IDF@bead359](https://github.com/espressif/esp-idf/commit/bead3599abd875d746e64cd6749574ff2c155adb))
- esp_websocket_client: Don't log the filename when logging "Websocket already stop" ([f0351ff](https://github.com/espressif/esp-protocols/commit/f0351ff), [IDF@10bde42](https://github.com/espressif/esp-idf/commit/10bde42551b479bd4bfccc9d3c6d983f8abe0b87))
- websocket: Add websocket unit tests ([9219ff7](https://github.com/espressif/esp-protocols/commit/9219ff7), [IDF@cd01a0c](https://github.com/espressif/esp-idf/commit/cd01a0ca81ef2ba5648fd7712c9bf45bbf252339))
- websockets: Set keepalive options after adding transport to the list ([86aa0b8](https://github.com/espressif/esp-protocols/commit/86aa0b8), [IDF@99805d8](https://github.com/espressif/esp-idf/commit/99805d880f41857702b3bbb35bc0dfaf7dec3aec))
- websocket: Add configurable ping interval ([1933367](https://github.com/espressif/esp-protocols/commit/1933367), [IDF@9ff9137](https://github.com/espressif/esp-idf/commit/9ff9137e7a8b64e956c1c63e95a48f4049ad571e))
- ws_transport: Add option to propagate control packets to the app ([95cf983](https://github.com/espressif/esp-protocols/commit/95cf983), [IDF#6307](https://github.com/espressif/esp-idf/issues/6307), [IDF@acc7bd2](https://github.com/espressif/esp-idf/commit/acc7bd2ca45c21033cbd02220a27c3c1ecdd5ad0))
- Add options for esp_http_client and esp_websocket_client to support keepalive ([8a6c320](https://github.com/espressif/esp-protocols/commit/8a6c320), [IDF@b53e46a](https://github.com/espressif/esp-idf/commit/b53e46a68e8671c73e8aafe2602de5ff5a77e3db))
- websocket: support mutual tls for websocket Closes https://github.com/espressif/esp-idf/issues/6059 ([d1dd6ec](https://github.com/espressif/esp-protocols/commit/d1dd6ec), [IDF#6059](https://github.com/espressif/esp-idf/issues/6059), [IDF@5ab774f](https://github.com/espressif/esp-idf/commit/5ab774f9d8e119fff56b566fa2f9bdad853bf701))
- Whitespace: Automated whitespace fixes (large commit) ([d376480](https://github.com/espressif/esp-protocols/commit/d376480), [IDF@66fb5a2](https://github.com/espressif/esp-idf/commit/66fb5a29bbdc2482d67c52e6f66b303378c9b789))
- Websocket client: avoid deadlock if stop called from event handler ([e90272c](https://github.com/espressif/esp-protocols/commit/e90272c), [IDF@c2bb076](https://github.com/espressif/esp-idf/commit/c2bb0762bb5c24cb170bc9c96fdadb86ae2f06e7))
- tcp_transport: Added internal API for underlying socket, used for custom select on connection end for WS ([6d12d06](https://github.com/espressif/esp-protocols/commit/6d12d06), [IDF@5e9f8b5](https://github.com/espressif/esp-idf/commit/5e9f8b52e7a87371370205a387b2d94e5ac6cbf9))
- ws_client: Added support for close frame, closing connection gracefully ([1455bc0](https://github.com/espressif/esp-protocols/commit/1455bc0), [IDF@b213f2c](https://github.com/espressif/esp-idf/commit/b213f2c6d3d78ba3a95005e3206d4ce370b8a649))
- driver, http_client, web_socket, tcp_transport: remove __FILE__ from log messages ([01b4f64](https://github.com/espressif/esp-protocols/commit/01b4f64), [IDF#5637](https://github.com/espressif/esp-idf/issues/5637), [IDF@caaf62b](https://github.com/espressif/esp-idf/commit/caaf62bdad965e6b58bba74171986414057f6757))
- websocket_client : fix some issues for websocket client ([6ab0aea](https://github.com/espressif/esp-protocols/commit/6ab0aea), [IDF@341e480](https://github.com/espressif/esp-idf/commit/341e48057349d92c3b8afe5f9c0fcd0aa47500b0))
- websocket: add configurable timeout for PONG not received ([b71c49c](https://github.com/espressif/esp-protocols/commit/b71c49c), [IDF@0049385](https://github.com/espressif/esp-idf/commit/0049385850daebfe2222c8f0526b896ffaeacdd9))
- websocket client: the client now aborts the connection if send fails. ([f8e3ba7](https://github.com/espressif/esp-protocols/commit/f8e3ba7), [IDF@6bebfc8](https://github.com/espressif/esp-idf/commit/6bebfc84f3ed9c96bcb331fd0d5b0bbb26ce07a4))
- ws_client: fix fragmented send setting proper opcodes ([7a5b2d5](https://github.com/espressif/esp-protocols/commit/7a5b2d5), [IDF#4974](https://github.com/espressif/esp-idf/issues/4974), [IDF@14992e6](https://github.com/espressif/esp-idf/commit/14992e62c5573d8b6076281f16b4fe11d6bc8f87))
- esp32: add implementation of esp_timer based on TG0 LAC timer ([17281a5](https://github.com/espressif/esp-protocols/commit/17281a5), [IDF@739eb05](https://github.com/espressif/esp-idf/commit/739eb05bb97736b70507e7ebcfee58e670672d23))
- tcp_transport/ws_client: websockets now correctly handle messages longer than buffer ([aec6a75](https://github.com/espressif/esp-protocols/commit/aec6a75), [IDF@ffeda30](https://github.com/espressif/esp-idf/commit/ffeda3003c92102d2d5b145c9adb3ea3105cbbda))
- websocket: added missing event data ([a6be8e2](https://github.com/espressif/esp-protocols/commit/a6be8e2), [IDF@7c0e376](https://github.com/espressif/esp-idf/commit/7c0e3765ec009acaf2ef439e98895598b5fd9aaf))
- Add User-Agent and additional headers to esp_websocket_client ([a48b0fa](https://github.com/espressif/esp-protocols/commit/a48b0fa), [IDF@9200250](https://github.com/espressif/esp-idf/commit/9200250f512146e348f84ebfc76f9e82e2070da2))
- ws_client: fix handling timeouts by websocket client. ([1fcc001](https://github.com/espressif/esp-protocols/commit/1fcc001), [IDF#4316](https://github.com/espressif/esp-idf/issues/4316), [IDF@e1f9829](https://github.com/espressif/esp-idf/commit/e1f982921a08022ca4307900fc058ccacccd26d0))
- websocket_client: fix locking mechanism in ws-client task and when sending data ([d0121b9](https://github.com/espressif/esp-protocols/commit/d0121b9), [IDF@7c5011f](https://github.com/espressif/esp-idf/commit/7c5011f411b7662feb50fd1e53114bec390d8c2e))
- 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 ([f55d839](https://github.com/espressif/esp-protocols/commit/f55d839), [IDF@abf9345](https://github.com/espressif/esp-idf/commit/abf9345b85559f4a922e8387f48336fb09994041))
- websocket_client: fix URI parsing to include also query part in websocket connection path ([f5a26c4](https://github.com/espressif/esp-protocols/commit/f5a26c4), [IDF@271e6c4](https://github.com/espressif/esp-idf/commit/271e6c4c9c57ca6715c1435a71fe3974cd2b18b3))
- ws_client: fixed posting to event loop with websocket timeout ([23f6a1d](https://github.com/espressif/esp-protocols/commit/23f6a1d), [IDF@5050506](https://github.com/espressif/esp-idf/commit/50505068c45fbe97611be9b7f2c30b8160cbb9e3))
- ws_client: added subprotocol configuration option to websocket client ([2553d65](https://github.com/espressif/esp-protocols/commit/2553d65), [IDF@de6ea39](https://github.com/espressif/esp-idf/commit/de6ea396f17be820153da6acaf977c1bf11806fb))
- ws_client: fixed path config issue when ws server configured using host and path instead of uri ([67949f9](https://github.com/espressif/esp-protocols/commit/67949f9), [IDF@c0ba9e1](https://github.com/espressif/esp-idf/commit/c0ba9e19fc6cff79f5760b991c259970bd4abeab))
- ws_client: fixed transport config option when server address configured as host, port, transport rather then uri ([bfc88ab](https://github.com/espressif/esp-protocols/commit/bfc88ab), [IDF@adee25d](https://github.com/espressif/esp-idf/commit/adee25d90e100a169e959f94db23621f6ffab0e6))
- esp_wifi: wifi support new event mechanism ([4d64495](https://github.com/espressif/esp-protocols/commit/4d64495), [IDF@003a987](https://github.com/espressif/esp-idf/commit/003a9872b7de69d799e9d37521cfbcaff9b37e85))
- tools: Mass fixing of empty prototypes (for -Wstrict-prototypes) ([da74a4a](https://github.com/espressif/esp-protocols/commit/da74a4a), [IDF@afbaf74](https://github.com/espressif/esp-idf/commit/afbaf74007e89d016dbade4072bf2e7a3874139a))
- ws_client: fix double delete issue in ws client initialization ([f718676](https://github.com/espressif/esp-protocols/commit/f718676), [IDF@9b507c4](https://github.com/espressif/esp-idf/commit/9b507c45c86cf491466d705cd7896c6f6e500d0d))
- ws_client: removed dependency on internal tcp_transport header ([13a40d2](https://github.com/espressif/esp-protocols/commit/13a40d2), [IDF@d143356](https://github.com/espressif/esp-idf/commit/d1433564ecfc885f80a7a261a88ab87d227cf1c2))
- examples: use new component registration api ([35d6f9a](https://github.com/espressif/esp-protocols/commit/35d6f9a), [IDF@6771eea](https://github.com/espressif/esp-idf/commit/6771eead80534c51efb2033c04769ef5893b4838))
- esp_websocket_client: Add websocket client component ([f3a0586](https://github.com/espressif/esp-protocols/commit/f3a0586), [IDF#2829](https://github.com/espressif/esp-idf/issues/2829), [IDF@2a2d932](https://github.com/espressif/esp-idf/commit/2a2d932cfe2404057c71bc91d9d9416200e67a03))

View File

@ -6,8 +6,8 @@ The `esp-websocket_client` component is a managed component for `esp-idf` that c
## Examples
Get started with example test [Example](examples/README.md):
Get started with example test [example](https://github.com/espressif/esp-protocols/tree/master/components/esp_websocket_client/examples):
## Documentation
* View the full [html documentation](https://espressif.github.io/esp-protocols/esp_websocket_client/index.html)
* View the full [html documentation](https://docs.espressif.com/projects/esp-protocols/esp_websocket_client/docs/latest/index.html)

View File

@ -848,8 +848,8 @@ static void esp_websocket_client_task(void *pv)
esp_tls_error_handle_t error_handle = esp_transport_get_error_handle(client->transport);
client->error_handle.esp_ws_handshake_status_code = esp_transport_ws_get_upgrade_request_status(client->transport);
if (error_handle) {
esp_websocket_client_error(client, "esp_transport_connect() failed with %d,\
transport_error=%s, tls_error_code=%i, tls_flags=%i, esp_ws_handshake_status_code=%d, errno=%d",
esp_websocket_client_error(client, "esp_transport_connect() failed with %d, "
"transport_error=%s, tls_error_code=%i, tls_flags=%i, esp_ws_handshake_status_code=%d, errno=%d",
result, esp_err_to_name(error_handle->last_error), error_handle->esp_tls_error_code,
error_handle->esp_tls_flags, client->error_handle.esp_ws_handshake_status_code, errno);
} else {

View File

@ -1,5 +1,6 @@
version: "0.0.4"
version: "1.0.0"
description: esp websocket client
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_websocket_client
dependencies:
idf:
version: ">=5.0"

View File

@ -0,0 +1,11 @@
components/mdns/examples:
disable:
- if: IDF_TARGET in ["esp32h2"]
components/mdns/tests/unit_test:
disable:
- if: IDF_TARGET in ["esp32h2"]
components/mdns/tests/test_apps:
disable:
- if: IDF_TARGET in ["esp32h2"]

8
components/mdns/.cz.yaml Normal file
View File

@ -0,0 +1,8 @@
---
commitizen:
bump_message: 'bump(mdns): $current_version -> $new_version'
pre_bump_hooks: python ../../ci/changelog.py mdns
tag_format: mdns-v$version
version: 1.1.0
version_files:
- idf_component.yml

View File

@ -0,0 +1,334 @@
# Changelog
## [1.1.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.1.0)
### Features
- Decouple main module from mdns-networking ([d238e93](https://github.com/espressif/esp-protocols/commit/d238e93))
### Bug Fixes
- Use idf-build-apps package for building mdns ([1a0a41f](https://github.com/espressif/esp-protocols/commit/1a0a41f))
- socket networking to init interfaces properly ([ee9b04f](https://github.com/espressif/esp-protocols/commit/ee9b04f))
- Removed unused internal lock from mdns_server struct ([a06fb77](https://github.com/espressif/esp-protocols/commit/a06fb77))
- Resolve conflicts only on self hosted items ([e69a9eb](https://github.com/espressif/esp-protocols/commit/e69a9eb), [#185](https://github.com/espressif/esp-protocols/issues/185))
- Fix memory issues reported by valgrind ([0a682e7](https://github.com/espressif/esp-protocols/commit/0a682e7))
### Updated
- docs(common): updated component and example links ([f48d9b2](https://github.com/espressif/esp-protocols/commit/f48d9b2))
- Add APIs to look up delegated services ([87dcd7d](https://github.com/espressif/esp-protocols/commit/87dcd7d))
- Fix deadly mdns crash ([4fa3023](https://github.com/espressif/esp-protocols/commit/4fa3023))
- docs(common): improving documentation ([ca3fce0](https://github.com/espressif/esp-protocols/commit/ca3fce0))
- append all ipv6 address in mdns answer ([5ed3e9a](https://github.com/espressif/esp-protocols/commit/5ed3e9a))
- test(mdns): Host tests to use IDF's esp_event_stub ([537d170](https://github.com/espressif/esp-protocols/commit/537d170))
## [1.0.9](https://github.com/espressif/esp-protocols/commits/mdns-v1.0.9)
### Features
- Add reverse lookup to the example and test ([d464ed7](https://github.com/espressif/esp-protocols/commit/d464ed7))
- Add support for IPv6 reverse query ([d4825f5](https://github.com/espressif/esp-protocols/commit/d4825f5))
### Bug Fixes
- Reintroduce missing CHANGELOGs ([200cbb3](https://github.com/espressif/esp-protocols/commit/200cbb3))
- use semaphore instead of task notification bits (IDFGH-9380) ([73f2800](https://github.com/espressif/esp-protocols/commit/73f2800), [IDF#10754](https://github.com/espressif/esp-idf/issues/10754))
### Updated
- ci(common): force scoping commit messages with components ([c55fcc0](https://github.com/espressif/esp-protocols/commit/c55fcc0))
- Add homepage URL and License to all components ([ef3f0ee](https://github.com/espressif/esp-protocols/commit/ef3f0ee))
- docs: fix of mdns link translation ([1c850dd](https://github.com/espressif/esp-protocols/commit/1c850dd))
- unite all tags under common structure py test: update tags under common structure ([c6db3ea](https://github.com/espressif/esp-protocols/commit/c6db3ea))
## [1.0.8](https://github.com/espressif/esp-protocols/commits/b9b4a75)
### Features
- Add support for IPv4 reverse query ([b87bef5](https://github.com/espressif/esp-protocols/commit/b87bef5))
### Bug Fixes
- Host test with IDFv5.1 ([fb8a2f0](https://github.com/espressif/esp-protocols/commit/fb8a2f0))
- Remove strict mode as it's invalid ([d0c9070](https://github.com/espressif/esp-protocols/commit/d0c9070))
- Allow setting instance name only after hostname set ([a8339e4](https://github.com/espressif/esp-protocols/commit/a8339e4), [#190](https://github.com/espressif/esp-protocols/issues/190))
- Make unit test executable with pytest ([12cfcb5](https://github.com/espressif/esp-protocols/commit/12cfcb5))
- AFL port layer per IDF-latest changes ([0247926](https://github.com/espressif/esp-protocols/commit/0247926))
### Updated
- bump the component version to 1.0.8 ([b9b4a75](https://github.com/espressif/esp-protocols/commit/b9b4a75))
- Make reverse query conditional per Kconfig ([91134f1](https://github.com/espressif/esp-protocols/commit/91134f1))
- Added badges with version of components to the respective README files ([e4c8a59](https://github.com/espressif/esp-protocols/commit/e4c8a59))
- fix some coverity reported issues ([c73c797](https://github.com/espressif/esp-protocols/commit/c73c797))
- Examples: using pytest.ini from top level directory ([aee016d](https://github.com/espressif/esp-protocols/commit/aee016d))
- mDNS: test_app pytest migration ([f71f61f](https://github.com/espressif/esp-protocols/commit/f71f61f))
- CI: fixing the files to be complient with pre-commit hooks ([945bd17](https://github.com/espressif/esp-protocols/commit/945bd17))
- prevent crash when hostname is null ([3498e86](https://github.com/espressif/esp-protocols/commit/3498e86))
- Example tests integration ([a045c1c](https://github.com/espressif/esp-protocols/commit/a045c1c))
- Replace hardcoded TTL values with named defines ([bb4c002](https://github.com/espressif/esp-protocols/commit/bb4c002))
- Fix add_service() to report error if no-hostname ([656ab21](https://github.com/espressif/esp-protocols/commit/656ab21))
## [1.0.7](https://github.com/espressif/esp-protocols/commits/088f7ac)
### Updated
- bump up the component version ([088f7ac](https://github.com/espressif/esp-protocols/commit/088f7ac))
- fix IPV4 only build and also update CI configuration ([e079f8b](https://github.com/espressif/esp-protocols/commit/e079f8b))
- add test configuration for IPV6 disabled build ([330332a](https://github.com/espressif/esp-protocols/commit/330332a))
## [1.0.6](https://github.com/espressif/esp-protocols/commits/48c157b)
### Bug Fixes
- Example makefile to add only mdns as extra comps ([d74c296](https://github.com/espressif/esp-protocols/commit/d74c296))
- ignore authoritative flag on reception ([415e04a](https://github.com/espressif/esp-protocols/commit/415e04a))
### Updated
- fix build issue with CONFIG_LWIP_IPV6 disabled ([48c157b](https://github.com/espressif/esp-protocols/commit/48c157b))
- fix bit order issue in DNS header flags ([c4e85bd](https://github.com/espressif/esp-protocols/commit/c4e85bd))
- updated package version to 0.1.19 ([469f953](https://github.com/espressif/esp-protocols/commit/469f953))
## [1.0.5](https://github.com/espressif/esp-protocols/commits/36de9af)
### Features
- Define explicit dependencies on esp-wifi ([36de9af](https://github.com/espressif/esp-protocols/commit/36de9af))
### Updated
- bugfix: mdns IPv6 address convert error ([238ee96](https://github.com/espressif/esp-protocols/commit/238ee96))
## [1.0.4](https://github.com/espressif/esp-protocols/commits/57afa38)
### Updated
- Bump asio/mdns/esp_websocket_client versions ([57afa38](https://github.com/espressif/esp-protocols/commit/57afa38))
- ignore format warnings ([d66f9dc](https://github.com/espressif/esp-protocols/commit/d66f9dc))
- Fix test_app build ([0b102f6](https://github.com/espressif/esp-protocols/commit/0b102f6))
## [1.0.3](https://github.com/espressif/esp-protocols/commits/4868689)
### Updated
- Updated mDNS to explicitely use esp-eth dependency if needed ([4868689](https://github.com/espressif/esp-protocols/commit/4868689), [IDF@5e19b9c](https://github.com/espressif/esp-idf/commit/5e19b9c9518ae253d82400ab24b86af8af832425))
## [1.0.2](https://github.com/espressif/esp-protocols/commits/8fe2a3a)
### Features
- fix bug when clean action memory ([81c219d](https://github.com/espressif/esp-protocols/commit/81c219d), [IDF@3d4deb9](https://github.com/espressif/esp-idf/commit/3d4deb972620cae8e8ce4d0050153cc6f39db372))
### Bug Fixes
- add the maximum number of services ([0191d6f](https://github.com/espressif/esp-protocols/commit/0191d6f), [IDF@ba458c6](https://github.com/espressif/esp-idf/commit/ba458c69cfb2f18478d73690c289b09641c62004))
- fix the exception when remove one of multiple service ([b26c866](https://github.com/espressif/esp-protocols/commit/b26c866), [IDF@696d733](https://github.com/espressif/esp-idf/commit/696d733eb04ee98f764dffdc82bcef51a724c9c6))
### Updated
- Minor fixes here and there ([8fe2a3a](https://github.com/espressif/esp-protocols/commit/8fe2a3a))
- mDNS: Initial version based on IDF 5.0 ([b6b20ad](https://github.com/espressif/esp-protocols/commit/b6b20ad))
- soc: moved kconfig options out of the target component. ([4a52cf2](https://github.com/espressif/esp-protocols/commit/4a52cf2), [IDF@d287209](https://github.com/espressif/esp-idf/commit/d2872095f93ed82fb91c776081bc1d032493d93e))
- cmake: fix issue with passing cxx_std option for GCC 11, a common workaround ([87c2699](https://github.com/espressif/esp-protocols/commit/87c2699), [IDF@ea0d212](https://github.com/espressif/esp-idf/commit/ea0d2123c806bd0ad77bc49843ee905cf9be65ff))
- kconfig: Changed default values of bool configs - Some bool configs were using default values true and false, instead of y and n. ([eb536a7](https://github.com/espressif/esp-protocols/commit/eb536a7), [IDF@25c5c21](https://github.com/espressif/esp-idf/commit/25c5c214f38ca690b03533e12fb5a4d774c7eae0))
- esp_netif: Remove tcpip_adapter compatibility layer ([3e93ea9](https://github.com/espressif/esp-protocols/commit/3e93ea9), [IDF@795b7ed](https://github.com/espressif/esp-idf/commit/795b7ed993784e3134195e12b0978504d83dfd56))
- Fix copyright messages, update API descrition ([2c764b1](https://github.com/espressif/esp-protocols/commit/2c764b1), [IDF@42ba8a8](https://github.com/espressif/esp-idf/commit/42ba8a8338fd5efd82498a5989fc5c105938d447))
- Add API to control custom network interfaces ([f836ae7](https://github.com/espressif/esp-protocols/commit/f836ae7), [IDF@b02468d](https://github.com/espressif/esp-idf/commit/b02468dc98d614f931d14cd8b5e2373ca51fb18d))
- CI/mdns: Fix fuzzer build ([4b5f24f](https://github.com/espressif/esp-protocols/commit/4b5f24f), [IDF@98e9426](https://github.com/espressif/esp-idf/commit/98e9426b660a6e825f811cccd45a0722cc801ccd))
- Add support for registering custom netif ([30f37c0](https://github.com/espressif/esp-protocols/commit/30f37c0), [IDF@bec42ff](https://github.com/espressif/esp-idf/commit/bec42ff85d5091d71e1cb1063bea20d7c6ac8c76))
- Indicate interface using esp_netif in search results ([ddc58e8](https://github.com/espressif/esp-protocols/commit/ddc58e8), [IDF@f8495f1](https://github.com/espressif/esp-idf/commit/f8495f1e86de9a8e7d046bf13d0ca04775041b4c))
- Use predefined interfaces to prepare for custom netifs ([fa951bf](https://github.com/espressif/esp-protocols/commit/fa951bf), [IDF@f90b3b7](https://github.com/espressif/esp-idf/commit/f90b3b798b446382d848f8c55c5e1653c81871cd))
- Prepare for dynamic esp-netif support ([605d1fa](https://github.com/espressif/esp-protocols/commit/605d1fa), [IDF@f9892f7](https://github.com/espressif/esp-idf/commit/f9892f77b88ba77dc6608ba746175f6dc64a7607))
- esp_hw_support/esp_system: Re-evaluate header inclusions and include directories ([58bf218](https://github.com/espressif/esp-protocols/commit/58bf218), [IDF@a9fda54](https://github.com/espressif/esp-idf/commit/a9fda54d39d1321005c3bc9b3cc268d0b7e9f052))
- system: move kconfig options out of target component ([ec491ec](https://github.com/espressif/esp-protocols/commit/ec491ec), [IDF@bb88338](https://github.com/espressif/esp-idf/commit/bb88338118957c2214a4c0a33cd4a152e2e1f8ba))
- Update to drop our own packet if bounced back ([94ae672](https://github.com/espressif/esp-protocols/commit/94ae672), [IDF@b5149e3](https://github.com/espressif/esp-idf/commit/b5149e3ee73728f790798e6757d732fe426e21c7))
- Fix potential read behind parsed packet ([e5a3a3d](https://github.com/espressif/esp-protocols/commit/e5a3a3d), [IDF@51a5de2](https://github.com/espressif/esp-idf/commit/51a5de2525d0e82adea2e298a0edcc9b2dee5edd))
- Fix memleak when adding delegated host ([7710ea9](https://github.com/espressif/esp-protocols/commit/7710ea9), [IDF@9cbdb87](https://github.com/espressif/esp-idf/commit/9cbdb8767bdf6e9745e895b2c5af74d0376965e7))
- Fix null-service issue when parsing packets ([034c55e](https://github.com/espressif/esp-protocols/commit/034c55e), [IDF#8307](https://github.com/espressif/esp-idf/issues/8307), [IDF@a57be7b](https://github.com/espressif/esp-idf/commit/a57be7b7d1135ddb29f9da636e9ad315f7fa1fa7))
- Update fuzzer test (add delegation, check memory) ([ec03fec](https://github.com/espressif/esp-protocols/commit/ec03fec), [IDF@2c10071](https://github.com/espressif/esp-idf/commit/2c1007156e01b4707b5c89d73cad05c0eef0264f))
- Remove legacy esp_event API ([5909e9e](https://github.com/espressif/esp-protocols/commit/5909e9e), [IDF@e46aa51](https://github.com/espressif/esp-idf/commit/e46aa515bdf5606a3d868f1034774d5fc96904b8))
- added missing includes ([82e2a5d](https://github.com/espressif/esp-protocols/commit/82e2a5d), [IDF@28d09c7](https://github.com/espressif/esp-idf/commit/28d09c7dbe145ffa6a7dd90531062d4f7669a9c8))
- Clear notification value in mdns_hostname_set ([48e4d40](https://github.com/espressif/esp-protocols/commit/48e4d40), [IDF@83a4ddb](https://github.com/espressif/esp-idf/commit/83a4ddbd250e2b386bccabb4705d4c58c1a22bcb))
- esp_timer: remove legacy ESP32 FRC timer implementation. ([ac6dcb6](https://github.com/espressif/esp-protocols/commit/ac6dcb6), [IDF@edb76f1](https://github.com/espressif/esp-idf/commit/edb76f14d6b3e925568ff04a87befe733ecc4517))
- freertos: Remove legacy data types ([085dbd8](https://github.com/espressif/esp-protocols/commit/085dbd8), [IDF@57fd78f](https://github.com/espressif/esp-idf/commit/57fd78f5baf93a368a82cf4b2e00ca17ffc09115))
- Tools: Custom baud-rate setup is not possible for IDF Monitor from menuconfig anymore ([f78e8cf](https://github.com/espressif/esp-protocols/commit/f78e8cf), [IDF@36a4011](https://github.com/espressif/esp-idf/commit/36a4011ff8985bfbae08ba0272194e6c3ef93bbf))
- Use memcpy() for copy to support non-text TXTs ([6cdf5ee](https://github.com/espressif/esp-protocols/commit/6cdf5ee), [IDF@6aefe9c](https://github.com/espressif/esp-idf/commit/6aefe9c18563ed567d384a956cf02b6f57d6894c))
- Support for null-value TXT records ([fcb5515](https://github.com/espressif/esp-protocols/commit/fcb5515), [IDF#8267](https://github.com/espressif/esp-idf/issues/8267), [IDF@23c2db4](https://github.com/espressif/esp-idf/commit/23c2db406dee8df09dbdba21cb7eef9fbca8bf27))
- Fix alloc issue if TXT has empty value ([9fdbe5f](https://github.com/espressif/esp-protocols/commit/9fdbe5f), [IDF@205f6ba](https://github.com/espressif/esp-idf/commit/205f6ba8541e12d958c7c56af5a7136090f12a0e))
- Fix random crash when defalt service instance queried ([20e6e9e](https://github.com/espressif/esp-protocols/commit/20e6e9e), [IDF@f46dffc](https://github.com/espressif/esp-idf/commit/f46dffca627e9578e49a510580f9754ec1e27e2e))
- Fix minor memory leaks when creating services ([c588263](https://github.com/espressif/esp-protocols/commit/c588263), [IDF@fad62cc](https://github.com/espressif/esp-idf/commit/fad62cc1ed3dce63b58297172a72a489d7af2d9d))
- Fix mDNS memory leak ([6258edf](https://github.com/espressif/esp-protocols/commit/6258edf), [IDF@119b4a9](https://github.com/espressif/esp-idf/commit/119b4a9dd12cf89cc5eaf63f8aa19730607ef30b))
- Fix mDNS memory leak ([c8b0d5e](https://github.com/espressif/esp-protocols/commit/c8b0d5e), [IDF@f5ffd53](https://github.com/espressif/esp-idf/commit/f5ffd53aeb402afc1333a98168bb2fa35d7cdc77))
- Use multi/uni-cast types in API ([5252b1d](https://github.com/espressif/esp-protocols/commit/5252b1d), [IDF@125c312](https://github.com/espressif/esp-idf/commit/125c3125524c71f4f48f635eda12e22fa3bca500))
- Allow for unicast PTR queries ([4e11cc8](https://github.com/espressif/esp-protocols/commit/4e11cc8), [IDF@7eeeb01](https://github.com/espressif/esp-idf/commit/7eeeb01ea705745b027bd8bc11d2b142418e9927))
- Fix potential null deref for ANY query type ([7af91ec](https://github.com/espressif/esp-protocols/commit/7af91ec), [IDF@99dd8ee](https://github.com/espressif/esp-idf/commit/99dd8eedb1a0e957f5f74344e3e4172e61c29ef8))
- Make fuzzer layers compatible with llvm>=6 ([01256d3](https://github.com/espressif/esp-protocols/commit/01256d3), [IDF@1882cbe](https://github.com/espressif/esp-idf/commit/1882cbe44e6140bebb2d27dc18af06dfcb0157f5))
- Fix copyright ([5a2d4ea](https://github.com/espressif/esp-protocols/commit/5a2d4ea), [IDF@c83678f](https://github.com/espressif/esp-idf/commit/c83678f64fe27844fc28050bde6433ccb04a0704))
- Add mDNS miss comment ([9de3f53](https://github.com/espressif/esp-protocols/commit/9de3f53), [IDF@08e0813](https://github.com/espressif/esp-idf/commit/08e081340d9d76d1244e9f2dc527e5ae370b1fbe))
- freertos: remove FREERTOS_ASSERT option ([bcabc8e](https://github.com/espressif/esp-protocols/commit/bcabc8e), [IDF@7255497](https://github.com/espressif/esp-idf/commit/72554971467a5edc9bd6e390cf8fe7b05e6ade81))
- Minor err print fix in socket-networking layer ([dfb27b3](https://github.com/espressif/esp-protocols/commit/dfb27b3), [IDF@f1b8f5c](https://github.com/espressif/esp-idf/commit/f1b8f5c1023df7d649161bc76f2bcc9a8f8f4d8b))
- unified errno format ([076c095](https://github.com/espressif/esp-protocols/commit/076c095), [IDF@87506f4](https://github.com/espressif/esp-idf/commit/87506f46e2922710f48a6b96ca75e53543ff45c4))
- always send A/AAAA records in announcements ([7dd0bc1](https://github.com/espressif/esp-protocols/commit/7dd0bc1), [IDF@456f80b](https://github.com/espressif/esp-idf/commit/456f80b754ebd0bd74e02c7febdf461c6b573b7a))
- filter instance name for ANY queries ([7e82a7c](https://github.com/espressif/esp-protocols/commit/7e82a7c), [IDF@5d0c473](https://github.com/espressif/esp-idf/commit/5d0c47303dd9ead0f2ad291dca1d4b7ce4e23b2b))
- Fix potential null deref reported by fuzzer test ([ae381b7](https://github.com/espressif/esp-protocols/commit/ae381b7), [IDF@cb5653f](https://github.com/espressif/esp-idf/commit/cb5653fd940a9cd41e8554a6d753fab46e0459d7))
- Minor fix of API description and API usage ([941dc5c](https://github.com/espressif/esp-protocols/commit/941dc5c), [IDF@c297301](https://github.com/espressif/esp-idf/commit/c297301ecc350f8315d7eaf78c72b4aba68d422a))
- Added results count to MDNS ([525c649](https://github.com/espressif/esp-protocols/commit/525c649), [IDF@f391d61](https://github.com/espressif/esp-idf/commit/f391d610e8185631b5361dc6c844c4c04aac30b1))
- fix mdns server instance mismatch ([f0839d9](https://github.com/espressif/esp-protocols/commit/f0839d9), [IDF@6173dd7](https://github.com/espressif/esp-idf/commit/6173dd78097216261277c20ebd92a53c68c47f89))
- support multiple instance for mdns service txt set ([69902ea](https://github.com/espressif/esp-protocols/commit/69902ea), [IDF@50f6302](https://github.com/espressif/esp-idf/commit/50f6302c5d7c0498fa1baa6fd6129d8233971a81))
- fix wrong PTR record count ([d0bbe88](https://github.com/espressif/esp-protocols/commit/d0bbe88), [IDF@5d3f815](https://github.com/espressif/esp-idf/commit/5d3f8157e0e481363ef93d54a29d957fc91cca86))
- Build & config: Remove leftover files from the unsupported "make" build system ([4a9d55e](https://github.com/espressif/esp-protocols/commit/4a9d55e), [IDF@766aa57](https://github.com/espressif/esp-idf/commit/766aa5708443099f3f033b739cda0e1de101cca6))
- Build & config: Remove the "make" build system ([be2a924](https://github.com/espressif/esp-protocols/commit/be2a924), [IDF@9c1d4f5](https://github.com/espressif/esp-idf/commit/9c1d4f5b549d6a7125e5c7c323c80d37361991cb))
- freertos: update freertos folder structure to match upstream ([76fcd41](https://github.com/espressif/esp-protocols/commit/76fcd41), [IDF@4846222](https://github.com/espressif/esp-idf/commit/48462221029c7da4b1ea233e9e781cd57ff91c7e))
- support service subtype ([fd8499c](https://github.com/espressif/esp-protocols/commit/fd8499c), [IDF#5508](https://github.com/espressif/esp-idf/issues/5508), [IDF@e7e8610](https://github.com/espressif/esp-idf/commit/e7e8610f563e0b8532a093ea8b803f0eb132fd0e))
- Fix parsing non-standard queries ([38b4fe2](https://github.com/espressif/esp-protocols/commit/38b4fe2), [IDF#7694](https://github.com/espressif/esp-idf/issues/7694), [IDF@d16f9ba](https://github.com/espressif/esp-idf/commit/d16f9bade5beab3785677dd5b39ebc4e9c895008))
- allow mutiple instances with same service type ([b266062](https://github.com/espressif/esp-protocols/commit/b266062), [IDF@b7a99f4](https://github.com/espressif/esp-idf/commit/b7a99f46587a69a2cd07e7616c3bb30b7b1a6edf))
- Update copyright header ([5e087d8](https://github.com/espressif/esp-protocols/commit/5e087d8), [IDF@2a2b95b](https://github.com/espressif/esp-idf/commit/2a2b95b9c22bc5090d87a4f4317288b64b14fcd9))
- Fix potential null dereference identified by fuzzer tests ([91a3d95](https://github.com/espressif/esp-protocols/commit/91a3d95), [IDF@e7dabb1](https://github.com/espressif/esp-idf/commit/e7dabb14f7c8fd9bd2bea55d8f1accc65323a1c0))
- components/bt: move config BT_RESERVE_DRAM from bluedroid to ESP32 controller ([6d6dd2b](https://github.com/espressif/esp-protocols/commit/6d6dd2b), [IDF@b310c06](https://github.com/espressif/esp-idf/commit/b310c062cd25f249e00dd03dd27baed783921630))
- add notification callback for async APIs ([52306e9](https://github.com/espressif/esp-protocols/commit/52306e9), [IDF@986603c](https://github.com/espressif/esp-idf/commit/986603cf07413b46c88c76c324bf500edcfb6171))
- add more mdns result attributes ([d37ab6d](https://github.com/espressif/esp-protocols/commit/d37ab6d), [IDF@76ec76c](https://github.com/espressif/esp-idf/commit/76ec76c12c871554147343bb7141da1e5de58011))
- Add host test using linux target ([5c55ea6](https://github.com/espressif/esp-protocols/commit/5c55ea6), [IDF@fc7e2d9](https://github.com/espressif/esp-idf/commit/fc7e2d9e908f61fb4b852cfae72aa5ff7c662ebc))
- Implement mdns_networking using BSD sockets ([0c71c7b](https://github.com/espressif/esp-protocols/commit/0c71c7b), [IDF@73dfe84](https://github.com/espressif/esp-idf/commit/73dfe84bf295a850edfad39b6b097a71f15964dc))
- fix crash when adding services without hostname set ([4c368c0](https://github.com/espressif/esp-protocols/commit/4c368c0), [IDF@5e98772](https://github.com/espressif/esp-idf/commit/5e98772eaf7e50d96cf2e6ecdfedcd928b61c864))
- Fix fuzzer IDF-mock layer ([af22753](https://github.com/espressif/esp-protocols/commit/af22753), [IDF@619235c](https://github.com/espressif/esp-idf/commit/619235c2ee5a1fe8411bd2be2de8798209f95902))
- Clean the main mdns module from lwip dependencies ([b0957e7](https://github.com/espressif/esp-protocols/commit/b0957e7), [IDF@54e3294](https://github.com/espressif/esp-idf/commit/54e329444a5dd19c51e84b5f1e16455a0f1c6225))
- Add asynchronous query API ([47c7266](https://github.com/espressif/esp-protocols/commit/47c7266), [IDF#7090](https://github.com/espressif/esp-idf/issues/7090), [IDF@d81482d](https://github.com/espressif/esp-idf/commit/d81482d699232b22f4a5cbee2a76199a5285dadb))
- Fix crashes reported by the fuzzer tests ([40da0d2](https://github.com/espressif/esp-protocols/commit/40da0d2), [IDF@4a2e726](https://github.com/espressif/esp-idf/commit/4a2e72677c6fb7681a7e2acd1a878d3deb114079))
- mdns/fuzzer: Fix non-instrumentation test to reproduce fuzzer issues ([5f6b6f9](https://github.com/espressif/esp-protocols/commit/5f6b6f9), [IDF@dae8033](https://github.com/espressif/esp-idf/commit/dae803335e6bc6d9751a360cd3f675ce4027853b))
- return ESP_OK rather than ERR_OK in API functions ([8a12082](https://github.com/espressif/esp-protocols/commit/8a12082), [IDF@2386113](https://github.com/espressif/esp-idf/commit/2386113972ee51ea93e9740d8c34bfe9289ce909))
- fix memory leak in mdns_free when adding delegated hostnames ([46f28a8](https://github.com/espressif/esp-protocols/commit/46f28a8), [IDF@0baee93](https://github.com/espressif/esp-idf/commit/0baee932111268c4a2103e1c1adeb7d99914a937))
- Support for One-Shot mDNS queries ([5a81eae](https://github.com/espressif/esp-protocols/commit/5a81eae), [IDF@f167238](https://github.com/espressif/esp-idf/commit/f167238fac37818aed75dc689eed54ad47528ab9))
- allow explicit txt value length ([2ddaee2](https://github.com/espressif/esp-protocols/commit/2ddaee2), [IDF@b4e0088](https://github.com/espressif/esp-idf/commit/b4e0088b68321acc4698b01faec7e2ffbe1e37c1))
- Fix crashes reported by the fuzzer ([27fc285](https://github.com/espressif/esp-protocols/commit/27fc285), [IDF@79ba738](https://github.com/espressif/esp-idf/commit/79ba738626d643d8c6f32bdcd455e0d2476f94c7))
- Minor correction of the test code ([93e6efe](https://github.com/espressif/esp-protocols/commit/93e6efe), [IDF@7d76245](https://github.com/espressif/esp-idf/commit/7d762451731cb305c3b090509827740f0195a496))
- Fix fuzzer from miss-interpreting adding services as timeouts ([bc4cda8](https://github.com/espressif/esp-protocols/commit/bc4cda8), [IDF@14099fe](https://github.com/espressif/esp-idf/commit/14099fe15efb1b0cde0a8370096c55bba62ff937))
- fix test script delayed response ([8a8d58d](https://github.com/espressif/esp-protocols/commit/8a8d58d), [IDF@a4f2639](https://github.com/espressif/esp-idf/commit/a4f263948c35c13340b6f4b59a649c5073787d5e))
- fix wrong SRV/PTR record handling ([402baeb](https://github.com/espressif/esp-protocols/commit/402baeb), [IDF@e613555](https://github.com/espressif/esp-idf/commit/e6135552d26480e39e11632437020535b1667b7a))
- fix wrong service hostname after mangling ([9fa25ef](https://github.com/espressif/esp-protocols/commit/9fa25ef), [IDF@439b31d](https://github.com/espressif/esp-idf/commit/439b31d065eddfdfb6eb4cf9c00454edfebc3d9b))
- fix empty address change announce packets ([121b525](https://github.com/espressif/esp-protocols/commit/121b525), [IDF@7bbb72d](https://github.com/espressif/esp-idf/commit/7bbb72d86540f04d37b0e2c4efb6dc66ee9c9ea0))
- fix mdns probe/reply behavior ([418fb60](https://github.com/espressif/esp-protocols/commit/418fb60), [IDF@d2a5d25](https://github.com/espressif/esp-idf/commit/d2a5d25984432d149ca31aea4a0d177f3509dd7b))
- make delegate host address a list ([4049b3b](https://github.com/espressif/esp-protocols/commit/4049b3b), [IDF@2d34352](https://github.com/espressif/esp-idf/commit/2d34352f3db0fa71366a838933a29138a90eb2af))
- add remove delegate host api ([c882119](https://github.com/espressif/esp-protocols/commit/c882119), [IDF@2174693](https://github.com/espressif/esp-idf/commit/2174693096b73ce93261611c44ecba647cd01859))
- add mdns delegation ([1eb5df9](https://github.com/espressif/esp-protocols/commit/1eb5df9), [IDF@401ff56](https://github.com/espressif/esp-idf/commit/401ff56cc1ad1d11284143a348cc0c0e4a363e98))
- fix memory free issue when repeating the query in reply ([b62b4b3](https://github.com/espressif/esp-protocols/commit/b62b4b3), [IDF@5f244c8](https://github.com/espressif/esp-idf/commit/5f244c86f29da46c17610563a245d1663a46b439))
- Fix of crash when wifi interface get deleted and mdns receives the packets ([4d8aec1](https://github.com/espressif/esp-protocols/commit/4d8aec1), [IDF#6973](https://github.com/espressif/esp-idf/issues/6973), [IDF@03de74a](https://github.com/espressif/esp-idf/commit/03de74a728d4b278f55e1fc30e0425483b806e80))
- Docs: Added README.md for lwip fuzzer tests ([6d64910](https://github.com/espressif/esp-protocols/commit/6d64910), [IDF@53c18a8](https://github.com/espressif/esp-idf/commit/53c18a85db104bb37ebeadec2faf5d42d764d0f9))
- Fixed the ip header TTL to be correctly set to 255 ([ab3fa69](https://github.com/espressif/esp-protocols/commit/ab3fa69), [IDF@5cce919](https://github.com/espressif/esp-idf/commit/5cce919cbef87f543bb9f5275b77b97b3b1ea67e))
- Fix parsing answers with questions when instance name not set ([c3a5826](https://github.com/espressif/esp-protocols/commit/c3a5826), [IDF#6598](https://github.com/espressif/esp-idf/issues/6598), [IDF@3404945](https://github.com/espressif/esp-idf/commit/34049454dfaf5132d9b258ef4d04921befc8997b))
- Fix the resolver to correctly parse it's own non-strict answers ([cbcbe4f](https://github.com/espressif/esp-protocols/commit/cbcbe4f), [IDF@b649603](https://github.com/espressif/esp-idf/commit/b649603a0d70ec804567f57752c3eddaed56198f))
- Add MDNS_STRICT_MODE config option ([adc3430](https://github.com/espressif/esp-protocols/commit/adc3430), [IDF@0eee315](https://github.com/espressif/esp-idf/commit/0eee31546dd4e6df0d1c1cc2740da0675dffb4bf))
- freertos: common config header ([c30617d](https://github.com/espressif/esp-protocols/commit/c30617d), [IDF@39cf818](https://github.com/espressif/esp-idf/commit/39cf818838b0259b3e00b3c198ad47b4add41939))
- Removed freeRTOS dependancies from fuzzer tests ([1e5eeb1](https://github.com/espressif/esp-protocols/commit/1e5eeb1), [IDF@5571694](https://github.com/espressif/esp-idf/commit/55716945a9908e057743d69e1d59399df03e49bd))
- mDNS: Updated APIs description and shows the warning when hostname contains domain name during the query ([22c7c0a](https://github.com/espressif/esp-protocols/commit/22c7c0a), [IDF#6590](https://github.com/espressif/esp-idf/issues/6590), [IDF@9f8d2b9](https://github.com/espressif/esp-idf/commit/9f8d2b944d2b3736a012e0dff1a8459b6941d295))
- components: Use CONFIG_LWIP_IPV6 to strip IPv6 function in components ([1623c0e](https://github.com/espressif/esp-protocols/commit/1623c0e), [IDF@da58235](https://github.com/espressif/esp-idf/commit/da58235a0ee262ff552c5f1155d531b5c31e8de6))
- add bound check when setting interface as duplicate ([b114ed6](https://github.com/espressif/esp-protocols/commit/b114ed6), [IDF@2b9d2c0](https://github.com/espressif/esp-idf/commit/2b9d2c06f54924b680c41ae641978c8d81612f65))
- mDNS: Fix of text length calculation when detecting a collision ([2ffd223](https://github.com/espressif/esp-protocols/commit/2ffd223), [IDF@be0ae1e](https://github.com/espressif/esp-idf/commit/be0ae1ebbbe9fae6ecf7de09e8d50cba063b61f4))
- global: fix sign-compare warnings ([1fe901f](https://github.com/espressif/esp-protocols/commit/1fe901f), [IDF@753a929](https://github.com/espressif/esp-idf/commit/753a9295259126217a9fe6ef1c5e9da21e9b4e28))
- lwip: Moved default SNTP API to esp_sntp.h ([2cf9fd8](https://github.com/espressif/esp-protocols/commit/2cf9fd8), [IDF@76f6dd6](https://github.com/espressif/esp-idf/commit/76f6dd6214ca583b1a94c7c553ccac739a27f6d5))
- Allow resolve its own non-strict answers ([89439e0](https://github.com/espressif/esp-protocols/commit/89439e0), [IDF#6190](https://github.com/espressif/esp-idf/issues/6190), [IDF@0693e17](https://github.com/espressif/esp-idf/commit/0693e172de392086b9bfd8cf1474d8d133af3298))
- mDNS: Fix of collision detection during txt length calculation ([becd5d0](https://github.com/espressif/esp-protocols/commit/becd5d0), [IDF#6114](https://github.com/espressif/esp-idf/issues/6114), [IDF@f33772c](https://github.com/espressif/esp-idf/commit/f33772c96037c795366e60082bdbbefe2a69165f))
- esp32c3: Apply one-liner/small changes for ESP32-C3 ([0d7a309](https://github.com/espressif/esp-protocols/commit/0d7a309), [IDF@5228d9f](https://github.com/espressif/esp-idf/commit/5228d9f9ced16118d87326f94d9f9dfd411e0be9))
- test: fix several test build error ([1fdffbb](https://github.com/espressif/esp-protocols/commit/1fdffbb), [IDF@b7ecccd](https://github.com/espressif/esp-idf/commit/b7ecccd9010f1deaba83de54374231c3c7f5b472))
- freertos: Add RISC-V port ([988d120](https://github.com/espressif/esp-protocols/commit/988d120), [IDF@87e13ba](https://github.com/espressif/esp-idf/commit/87e13baaf12fe6deae715d95e912a310fea4ba88))
- Fix wrong mdns source address if lwIP IPv6 zones disabled ([fd47df3](https://github.com/espressif/esp-protocols/commit/fd47df3), [IDF@7ac9761](https://github.com/espressif/esp-idf/commit/7ac97616c119e4d2f4cdd377dfc5abbf75ec5e30))
- Whitespace: Automated whitespace fixes (large commit) ([2cb3a6e](https://github.com/espressif/esp-protocols/commit/2cb3a6e), [IDF@66fb5a2](https://github.com/espressif/esp-idf/commit/66fb5a29bbdc2482d67c52e6f66b303378c9b789))
- test_compile_fuzzers: Fix include paths for host build ([825652f](https://github.com/espressif/esp-protocols/commit/825652f), [IDF@98a0cc7](https://github.com/espressif/esp-idf/commit/98a0cc783f701b238bea232b53250a538d34920a))
- CI: Add a test to pre-check fuzzer tests compilation before weekly run ([fc53888](https://github.com/espressif/esp-protocols/commit/fc53888), [IDF@637f5c0](https://github.com/espressif/esp-idf/commit/637f5c0a6842c42ee6cf7f41d3c5ae0cb28a68af))
- soc: descriptive part occupy whole component ([7635c04](https://github.com/espressif/esp-protocols/commit/7635c04), [IDF@79887fd](https://github.com/espressif/esp-idf/commit/79887fdc6c3d9a2e509cc189bb43c998d3f0f4ee))
- Coredump config option rename throughout IDF ([d5fe42b](https://github.com/espressif/esp-protocols/commit/d5fe42b), [IDF@20af94f](https://github.com/espressif/esp-idf/commit/20af94ff53c5147a76342800d007a6c49be50a7b))
- mdns, dns, dhcp, dhcps: update fuzzer test to work in CI ([e0bc60a](https://github.com/espressif/esp-protocols/commit/e0bc60a), [IDF@a43c06a](https://github.com/espressif/esp-idf/commit/a43c06a592bcf9404297b22268c33bb7a246632c))
- cmock: added cmock as component ([9772e49](https://github.com/espressif/esp-protocols/commit/9772e49), [IDF@20c068e](https://github.com/espressif/esp-idf/commit/20c068ef3b49999387896b90f8011b02f718485f))
- Support queries in responses in mDNS non-strict mode ([6021a88](https://github.com/espressif/esp-protocols/commit/6021a88), [IDF#5521](https://github.com/espressif/esp-idf/issues/5521), [IDF@bcfa36d](https://github.com/espressif/esp-idf/commit/bcfa36db8ffff997f1f95eaf6b011ffc4d46a10f))
- Fix include query ID in reponses ([78f71ec](https://github.com/espressif/esp-protocols/commit/78f71ec), [IDF#5574](https://github.com/espressif/esp-idf/issues/5574), [IDF@f62e321](https://github.com/espressif/esp-idf/commit/f62e321d87c1d520cccca951715c27730e06607a))
- Allow config mDNS task stack size ([3319844](https://github.com/espressif/esp-protocols/commit/3319844), [IDF@cf7e48c](https://github.com/espressif/esp-idf/commit/cf7e48c779edd84c3f99d5e8ed81027932302382))
- Remove mbedtls dependency ([ac70c9a](https://github.com/espressif/esp-protocols/commit/ac70c9a), [IDF@f4a4549](https://github.com/espressif/esp-idf/commit/f4a4549a344e7ff2444a188adbebbc136b47a7bb))
- limit the GOT_IP6_EVENT to only known network interfaces ([2b7d43e](https://github.com/espressif/esp-protocols/commit/2b7d43e), [IDF@ab8cab1](https://github.com/espressif/esp-idf/commit/ab8cab1c553ee5312ef47a7dea002f2585605006))
- esp32: add implementation of esp_timer based on TG0 LAC timer ([4eb3e89](https://github.com/espressif/esp-protocols/commit/4eb3e89), [IDF@739eb05](https://github.com/espressif/esp-idf/commit/739eb05bb97736b70507e7ebcfee58e670672d23))
- fixed typos in the variable names and the comments ([b5e5a64](https://github.com/espressif/esp-protocols/commit/b5e5a64), [IDF@ecca39e](https://github.com/espressif/esp-idf/commit/ecca39e19f663e32e16aef2a09df15443de347e9))
- fix preset of esp_netif ptr for local interfaces ([6713ffe](https://github.com/espressif/esp-protocols/commit/6713ffe), [IDF@09e36f9](https://github.com/espressif/esp-idf/commit/09e36f9f3354092b2a528baaaaccab28ff4774d6))
- fixed crash on event during deinit ([817c4fd](https://github.com/espressif/esp-protocols/commit/817c4fd), [IDF@eaa2f12](https://github.com/espressif/esp-idf/commit/eaa2f12d6761710d2633b4934fe09f6f45e20f4f))
- respond to discovery with the proper pseudo name _services._dns-sd._udp ([8f0dc6d](https://github.com/espressif/esp-protocols/commit/8f0dc6d), [IDF#4369](https://github.com/espressif/esp-idf/issues/4369), [IDF@de17a14](https://github.com/espressif/esp-idf/commit/de17a1487f8ba6f432b06199f2261132ec6e735f))
- fixed forgotten merge conflicts in debug code ([d20666f](https://github.com/espressif/esp-protocols/commit/d20666f), [IDF@d9433ef](https://github.com/espressif/esp-idf/commit/d9433ef69223a32d05abdca543fb530f2e6679e4))
- add missing include of esp_task.h ([662a4ce](https://github.com/espressif/esp-protocols/commit/662a4ce), [IDF@5884b80](https://github.com/espressif/esp-idf/commit/5884b80908d680874e27fa0c8b2df85b69d03dd3))
- add configuration values for task priority, affinity and internal service timeouts ([fb1de80](https://github.com/espressif/esp-protocols/commit/fb1de80), [IDF@c6f38f0](https://github.com/espressif/esp-idf/commit/c6f38f04f8eec1aae937cc87c111609772681cb3))
- 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 ([1f35e9a](https://github.com/espressif/esp-protocols/commit/1f35e9a), [IDF@7f5cda1](https://github.com/espressif/esp-idf/commit/7f5cda1b825586903f85dc4ad7736b35712e46d7))
- update mdns to use esp-netif for mdns supported services such as STA, AP, ETH ([48b819b](https://github.com/espressif/esp-protocols/commit/48b819b), [IDF@19e24fe](https://github.com/espressif/esp-idf/commit/19e24fe61ed5ea6698dfd5e1f427e783360aa846))
- esp_netif: Introduction of esp-netif component as a replacement of tcpip_adpter ([53e2aa3](https://github.com/espressif/esp-protocols/commit/53e2aa3), [IDF@ffe043b](https://github.com/espressif/esp-idf/commit/ffe043b1a81a0f9e1cc2cfa8873e21318ec89143))
- examples: removed ip4addr_ntoa and used prefered IP2STR for displaying IP addresses ([3cc6446](https://github.com/espressif/esp-protocols/commit/3cc6446), [IDF@ec9f245](https://github.com/espressif/esp-idf/commit/ec9f245dd35d3e8e7b19a8dec5e05e003dc21f39))
- esp_event, mdns: fixes for CONFIG_ETH_ENABLED=n ([248b11b](https://github.com/espressif/esp-protocols/commit/248b11b), [IDF@569ad75](https://github.com/espressif/esp-idf/commit/569ad7545c32a2f1d0eff3f1e81df70fb76ad125))
- build and link hello-world for esp32s2beta ([901124b](https://github.com/espressif/esp-protocols/commit/901124b), [IDF@84b2f9f](https://github.com/espressif/esp-idf/commit/84b2f9f14d16533c84db2210f13a24cd817e0b0a))
- fix crash for hostname queries ([f6ff165](https://github.com/espressif/esp-protocols/commit/f6ff165), [IDF#4224](https://github.com/espressif/esp-idf/issues/4224), [IDF@3d11700](https://github.com/espressif/esp-idf/commit/3d1170031b340a231949fdc0d9c46d87af0d1b5d))
- fix possible race condition when checking DHCP status on WIFI_EVENT_STA_CONNECTED event. ([f44c569](https://github.com/espressif/esp-protocols/commit/f44c569), [IDF@7f410a0](https://github.com/espressif/esp-idf/commit/7f410a0bcbafa85dba05807c53c3c38999506509))
- use constant size of AAAA answer in mdns packets instead of deriving from lwip struct size, since the struct could contain also zones ([286c646](https://github.com/espressif/esp-protocols/commit/286c646), [IDF@e5e31c5](https://github.com/espressif/esp-idf/commit/e5e31c5d0172d68fd207fa31cc5d3bba82dad020))
- esp_wifi: wifi support new event mechanism ([c70d527](https://github.com/espressif/esp-protocols/commit/c70d527), [IDF@003a987](https://github.com/espressif/esp-idf/commit/003a9872b7de69d799e9d37521cfbcaff9b37e85))
- fix missing bye packet if services removed with mdns_service_remove_all() or mdns_free() ([7cdf96c](https://github.com/espressif/esp-protocols/commit/7cdf96c), [IDF#3660](https://github.com/espressif/esp-idf/issues/3660), [IDF@a001998](https://github.com/espressif/esp-idf/commit/a001998d5283b29ca9a374adf7cef3357b39a03a))
- mdns_service_remove_all doesn't take an argument ([407875d](https://github.com/espressif/esp-protocols/commit/407875d), [IDF@c2764f6](https://github.com/espressif/esp-idf/commit/c2764f6fe85681cfaf5dbbe168295284f09c09cd))
- tools: Mass fixing of empty prototypes (for -Wstrict-prototypes) ([3e753f5](https://github.com/espressif/esp-protocols/commit/3e753f5), [IDF@afbaf74](https://github.com/espressif/esp-idf/commit/afbaf74007e89d016dbade4072bf2e7a3874139a))
- fix ignoring mdns packet with some invalid name entries in question field ([144d4ad](https://github.com/espressif/esp-protocols/commit/144d4ad), [IDF@4bd4c7c](https://github.com/espressif/esp-idf/commit/4bd4c7caf3f9ef8402c5a27ab44561537407eb60))
- add esp_eth component ([680bad6](https://github.com/espressif/esp-protocols/commit/680bad6), [IDF@90c4827](https://github.com/espressif/esp-idf/commit/90c4827bd22aa61894a5b22b3b39247a7e44d6cf))
- components: use new component registration api ([7fb6686](https://github.com/espressif/esp-protocols/commit/7fb6686), [IDF@9eccd7c](https://github.com/espressif/esp-idf/commit/9eccd7c0826d6cc2e9de59304d1e5f76c0063ccf))
- fix static analysis warnings ([4912bef](https://github.com/espressif/esp-protocols/commit/4912bef), [IDF@c34de4c](https://github.com/espressif/esp-idf/commit/c34de4cba658e8331f8a3ab2f466190c7640595b))
- added initial suite of api unit tests ([181a22e](https://github.com/espressif/esp-protocols/commit/181a22e), [IDF@e680191](https://github.com/espressif/esp-idf/commit/e6801912c5c4861f828ab1f447280628bba9a5d7))
- mdns tests: adapt mdns fuzzer test to compile with event loop library ([4172219](https://github.com/espressif/esp-protocols/commit/4172219), [IDF@38d15cb](https://github.com/espressif/esp-idf/commit/38d15cbd637e8b8baacda9fc43e8e99d224530f5))
- fixed mdns crashing on reception of txt packet without a corresponding service closes #2866 ([98d2c1a](https://github.com/espressif/esp-protocols/commit/98d2c1a), [IDF@af48977](https://github.com/espressif/esp-idf/commit/af48977f21cea6b18dae10b2c8b64a78acfc647f))
- use const char* for mdns txt items types to remove warning when assigning ([84cbb1f](https://github.com/espressif/esp-protocols/commit/84cbb1f), [IDF@c050a75](https://github.com/espressif/esp-idf/commit/c050a75616803c7871ef11c060e440fae09000d9))
- updated doxygen comments documenting mdns api ([4c6818e](https://github.com/espressif/esp-protocols/commit/4c6818e), [IDF#1718](https://github.com/espressif/esp-idf/issues/1718), [IDF@a851aac](https://github.com/espressif/esp-idf/commit/a851aac255311124529f504486ca55bad15c1951))
- update mdns_out_question_s to be in line with mdns_parsed_question_s struct ([c440114](https://github.com/espressif/esp-protocols/commit/c440114), [IDF#1568]( https://github.com/espressif/esp-idf/issues/1568), [IDF@eddd5c4](https://github.com/espressif/esp-idf/commit/eddd5c4f2c686d9a1d6d3258569cc33752e78880))
- use esp_event library to handle events ([6ea0ea9](https://github.com/espressif/esp-protocols/commit/6ea0ea9), [IDF@a2d5952](https://github.com/espressif/esp-idf/commit/a2d59525e53099ee1ad63c3d60ff853f573ab535))
- fuzzer tests: update of mdns and lwip host compilation for fuzzer testing ([d9aec9f](https://github.com/espressif/esp-protocols/commit/d9aec9f), [IDF@bc60bbb](https://github.com/espressif/esp-idf/commit/bc60bbbeaf89f2bbfc5db4bd4f1e7ace81a2ab37))
- fix possible crash when probing on particular interface with duplicated service instances due to naming conflicts on network ([985e691](https://github.com/espressif/esp-protocols/commit/985e691), [IDF@265e983](https://github.com/espressif/esp-idf/commit/265e983a452a7eaefc1662cdc0e6ed839a37fe1a))
- enable pcbs before starting service thread to avoid updating pcb's internal variables from concurent tasks ([75deebb](https://github.com/espressif/esp-protocols/commit/75deebb), [IDF@c87f0cb](https://github.com/espressif/esp-idf/commit/c87f0cb6cad3c36b077f4aaeb1ca52fe6ed0cdaf))
- fix possible deadlock on mdns deinit calling mdns_free() ([fdd27dc](https://github.com/espressif/esp-protocols/commit/fdd27dc), [IDF#1696](https://github.com/espressif/esp-idf/issues/1696), [IDF@48b5501](https://github.com/espressif/esp-idf/commit/48b5501c250ed90da51a55ad4fc18e09f466a517))
- mdsn: fix race condition in updating packet data from user task when failed to allocate or queue a new service ([2ec3b55](https://github.com/espressif/esp-protocols/commit/2ec3b55), [IDF@021dc5d](https://github.com/espressif/esp-idf/commit/021dc5d453e21e2d1707f194668e69cf63ef4e84))
- fix possible crash when packet scheduled to transmit contained service which might have been already removed ([450cbf0](https://github.com/espressif/esp-protocols/commit/450cbf0), [IDF@67051a2](https://github.com/espressif/esp-idf/commit/67051a286ba60a01d4755c3682129153c2f95953))
- use binary semaphore instead of mutex when searching ([34f6d8d](https://github.com/espressif/esp-protocols/commit/34f6d8d), [IDF@eef0b50](https://github.com/espressif/esp-idf/commit/eef0b5090aee87efef1a6a37772b3b88c9ce8df8))
- fix memory leak in pbuf if tcpipadapter failed to get netif ([b6efc68](https://github.com/espressif/esp-protocols/commit/b6efc68), [IDF@8462751](https://github.com/espressif/esp-idf/commit/8462751f95a3ff18bdc1b01d02fabd1829fd9135))
- fix malfuctional query_txt ([90e4bab](https://github.com/espressif/esp-protocols/commit/90e4bab), [IDF@1a02773](https://github.com/espressif/esp-idf/commit/1a027734af06abf08fcb1c34ee65bdf50d12be4d))
- fix possible crash when mdns_free called while action queue not empty ([c546ab8](https://github.com/espressif/esp-protocols/commit/c546ab8), [IDF@206b47c](https://github.com/espressif/esp-idf/commit/206b47c03aca0acdf40d1d9c250e18aeddfe1bd7))
- fix memory leak when query for service receives multiple ptr entries for one instance ([6582b41](https://github.com/espressif/esp-protocols/commit/6582b41), [IDF@9a4da97](https://github.com/espressif/esp-idf/commit/9a4da97fb4b3c241998cb969a08c3a917ffb4cd1))
- fix crash after init if no memory for task ([358d26c](https://github.com/espressif/esp-protocols/commit/358d26c), [IDF@a47768d](https://github.com/espressif/esp-idf/commit/a47768dc4e4750fd7e1c29b15d6e2dd3c76e6591))
- fixed crash on free undefined ptr after skipped strdup ([2ac83d0](https://github.com/espressif/esp-protocols/commit/2ac83d0), [IDF@e0a8044](https://github.com/espressif/esp-idf/commit/e0a8044a16907e642001b883469618a999dbe6db))
- Correct Kconfigs according to the coding style ([98e3171](https://github.com/espressif/esp-protocols/commit/98e3171), [IDF@37126d3](https://github.com/espressif/esp-idf/commit/37126d3451eabb44eeeb48b8e2ee554dc233e2a8))
- fix networking running udp_sendif from lwip thread ([2f85c07](https://github.com/espressif/esp-protocols/commit/2f85c07), [IDF@f7d4a4b](https://github.com/espressif/esp-idf/commit/f7d4a4be6a9e0b0ac5edb9400d3b123dbbed2ffc))
- fixed static memory leak ([b30a7fe](https://github.com/espressif/esp-protocols/commit/b30a7fe), [IDF@6bb68a5](https://github.com/espressif/esp-idf/commit/6bb68a5a7567a94c3605136d44960ff060c74663))
- check all mallocs for failure and add default hook to log error with free heap ([7a4fdad](https://github.com/espressif/esp-protocols/commit/7a4fdad), [IDF@c8cb4cd](https://github.com/espressif/esp-idf/commit/c8cb4cd3c8eb56d5901ade03302ad1231d7f3de5))
- resolve memory leak when txt record received multiple times ([b4e5742](https://github.com/espressif/esp-protocols/commit/b4e5742), [IDF@a6b2b73](https://github.com/espressif/esp-idf/commit/a6b2b73f03bbb75a39685ddba6cf877fd1e5e6d7))
- skip sending search when finished, not properly locked timer task ([2763bcd](https://github.com/espressif/esp-protocols/commit/2763bcd), [IDF@31163f0](https://github.com/espressif/esp-idf/commit/31163f02d5c414d8b492dce6f729b43a0061581b))
- sending search packets also in probing and announcing state ([8cd0e8a](https://github.com/espressif/esp-protocols/commit/8cd0e8a), [IDF@d16762a](https://github.com/espressif/esp-idf/commit/d16762a036e35ce86ece86bb44e6e99f9cc7c431))
- fixed crashes on network changes ([9b3b41c](https://github.com/espressif/esp-protocols/commit/9b3b41c), [IDF@097282a](https://github.com/espressif/esp-idf/commit/097282a8e3f85958747430d9931ce0a545d37700))
- Update network code for mDNS to work with newest LwIP ([ea23007](https://github.com/espressif/esp-protocols/commit/ea23007), [IDF@3ec0e7e](https://github.com/espressif/esp-idf/commit/3ec0e7e2d2ddea70e9f8fb5025664d0fe24c301a))
- bugfix: mdns_service_txt_set() wasn't allocating memory for TXT records ([0c17121](https://github.com/espressif/esp-protocols/commit/0c17121), [IDF@e5e2702](https://github.com/espressif/esp-idf/commit/e5e2702ca3f63a29da57eb138f75a20c74fb2a94))
- cmake: make main a component again ([67173f6](https://github.com/espressif/esp-protocols/commit/67173f6), [IDF@d9939ce](https://github.com/espressif/esp-idf/commit/d9939cedd9b44d63dc148354c3a0a139b9c7113d))
- Feature/sync lwip as submodule ([fed787f](https://github.com/espressif/esp-protocols/commit/fed787f), [IDF@3578fe3](https://github.com/espressif/esp-idf/commit/3578fe39e01ba0c2d54824ac70c3276502661c6b))
- Fix a portion of the queries are issued with the wildcard query type ([b4ab30b](https://github.com/espressif/esp-protocols/commit/b4ab30b), [IDF@f3f0445](https://github.com/espressif/esp-idf/commit/f3f0445f4db7c9ad97ae10a9728767337aa7bb62))
- added CI job for AFL fuzzer tests ([dd71494](https://github.com/espressif/esp-protocols/commit/dd71494), [IDF@0c14764](https://github.com/espressif/esp-idf/commit/0c147648f7642d058b63fbe2ddd5de31c2326304))
- Minor fix for mdns_service_remove() ([39de491](https://github.com/espressif/esp-protocols/commit/39de491), [IDF@5c7eb7e](https://github.com/espressif/esp-idf/commit/5c7eb7e27be7508130459d896cf7d13ffefda87f))
- Replace all DOS line endings with Unix ([19acac7](https://github.com/espressif/esp-protocols/commit/19acac7), [IDF@a67d5d8](https://github.com/espressif/esp-idf/commit/a67d5d89e0e90390fa7ff02816a6a79008d75d40))
- remove executable permission from source files ([98069f9](https://github.com/espressif/esp-protocols/commit/98069f9), [IDF@cb649e4](https://github.com/espressif/esp-idf/commit/cb649e452f3c64a7db1f4a61e162a16b70248204))
- Fixed nullptr dereference in MDNS.c ([ad29d34](https://github.com/espressif/esp-protocols/commit/ad29d34), [IDF@fffbf7b](https://github.com/espressif/esp-idf/commit/fffbf7b75065b5852e064e04b0c5102dd0fc2244))
- MDNS-Fuzzer: AFL fuzzer tests for mdsn packet parser ([9f1be36](https://github.com/espressif/esp-protocols/commit/9f1be36), [IDF@e983230](https://github.com/espressif/esp-idf/commit/e983230be933fb83cebdd1945ba6539a7dc99b28))
- cmake: Add component dependency support ([c7701d4](https://github.com/espressif/esp-protocols/commit/c7701d4), [IDF@1cb5712](https://github.com/espressif/esp-idf/commit/1cb5712463a8963cd3e8331da90fb5e03f13575f))
- cmake: Remove defaults for COMPONENT_SRCDIRS, COMPONENT_SRCS, COMPONENT_ADD_INCLUDEDIRS ([f1ccc40](https://github.com/espressif/esp-protocols/commit/f1ccc40), [IDF@4f1a856](https://github.com/espressif/esp-idf/commit/4f1a856dbfd752336cd71730105e02ad8c045541))
- build system: Initial cmake support, work in progress ([84bd1d7](https://github.com/espressif/esp-protocols/commit/84bd1d7), [IDF@c671a0c](https://github.com/espressif/esp-idf/commit/c671a0c3ebf90f18576d6db55b51b62730c58301))
- fix the bug that in mdns test code redefine esp_err_t to uint32_t, which should be int32_t ([259d3fc](https://github.com/espressif/esp-protocols/commit/259d3fc), [IDF@81e4cad](https://github.com/espressif/esp-idf/commit/81e4cad61593cde879a5c44a08060d9d336e5a3f))
- Fix exception when service is removed while there are pending packets that depend on it ([7784d00](https://github.com/espressif/esp-protocols/commit/7784d00), [IDF@421c6f1](https://github.com/espressif/esp-idf/commit/421c6f154b10d9253b78875ab28ee6bdcaaaf3c0))
- Fix case where service is NULL and that will cause exception ([bce7d52](https://github.com/espressif/esp-protocols/commit/bce7d52), [IDF@4fa130a](https://github.com/espressif/esp-idf/commit/4fa130ae4fb5de99ddddc5a7bed7e26ae645591c))
- Fix issue with some mDNS parsers ([ef924f1](https://github.com/espressif/esp-protocols/commit/ef924f1), [IDF@51dde19](https://github.com/espressif/esp-idf/commit/51dde19a765533af67fc7be21f116641773a9be4))
- Import mDNS changes ([ad8c92d](https://github.com/espressif/esp-protocols/commit/ad8c92d), [IDF@4bddbc0](https://github.com/espressif/esp-idf/commit/4bddbc031cee83935c0e4df1dc72cc7000c97ba5))
- Fix compilation errors when using gcc-7.2.0 for the crosstool-ng toolchain ([3aa605f](https://github.com/espressif/esp-protocols/commit/3aa605f), [IDF@519edc3](https://github.com/espressif/esp-idf/commit/519edc332dae0160069fd790467cde8de78f1a0e))
- components/mdns: wrong Message compression detect ([00a72b8](https://github.com/espressif/esp-protocols/commit/00a72b8), [IDF@6e24566](https://github.com/espressif/esp-idf/commit/6e24566186c52dc5432b6b25c81abda577c21e85))
- fix leak after _mdns_create_service if we have a malloc error. ([907e7ee](https://github.com/espressif/esp-protocols/commit/907e7ee), [IDF@b6b36bd](https://github.com/espressif/esp-idf/commit/b6b36bd9ddf169039a5528f8b766048d97b975f7))
- Use LwIP IPC for low-level API calls ([b367484](https://github.com/espressif/esp-protocols/commit/b367484), [IDF@713964f](https://github.com/espressif/esp-idf/commit/713964fe9e98b4fa34145c497b7ab638dc57614c))
- Add AFL fuzz test ([4a8582f](https://github.com/espressif/esp-protocols/commit/4a8582f), [IDF@4c26227](https://github.com/espressif/esp-idf/commit/4c2622755d92efa1818d062d433725553437993c))
- implement fixes for issues found while fuzz testing ([75de31c](https://github.com/espressif/esp-protocols/commit/75de31c), [IDF@99d3990](https://github.com/espressif/esp-idf/commit/99d39909c4f19c63909d663e927ac0a8933a3ed5))
- add simple dns-sd meta query support ([4acf639](https://github.com/espressif/esp-protocols/commit/4acf639), [IDF@96e8a3c](https://github.com/espressif/esp-idf/commit/96e8a3c725095562d2725aaefa15adcfc5d78dd5))
- address security issues with mDNS ([91bb509](https://github.com/espressif/esp-protocols/commit/91bb509), [IDF@c89e11c](https://github.com/espressif/esp-idf/commit/c89e11c8fa64641edddf9a055745d825ae3fab9d))
- Initial mDNS component and example ([7fbf8e5](https://github.com/espressif/esp-protocols/commit/7fbf8e5), [IDF@dd3f18d](https://github.com/espressif/esp-idf/commit/dd3f18d2d88ee78909d4af2840dfdf0b9f715f28))

View File

@ -6,7 +6,7 @@ endif()
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
set(dependencies esp_event esp_netif_linux esp_timer_linux esp_system)
set(dependencies esp_netif_linux esp_timer_linux esp_system)
set(srcs "mdns.c" ${MDNS_NETWORKING})
else()
set(dependencies lwip console esp_netif)

202
components/mdns/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@ -6,9 +6,9 @@ mDNS is a multicast UDP service that is used to provide local network service an
## Examples
Get started with example test [Example](examples/README.md):
Get started with example test [Example](https://github.com/espressif/esp-protocols/tree/master/components/mdns/examples):
## Documentation
* View the full [documentation(English)](https://espressif.github.io/esp-protocols/mdns/en/index.html)
* View the full [documentation(Chinese)](https://espressif.github.io/esp-protocols/mdns/zh_CN/index.html)
* View the full [documentation(English)](https://docs.espressif.com/projects/esp-protocols/mdns/docs/latest/en/index.html)
* View the full [documentation(Chinese)](https://docs.espressif.com/projects/esp-protocols/mdns/latest/zh_CN/index.html)

View File

@ -93,8 +93,10 @@ static void mdns_print_results(mdns_result_t *results)
mdns_ip_addr_t *a = NULL;
int i = 1, t;
while (r) {
printf("%d: Interface: %s, Type: %s, TTL: %u\n", i++, esp_netif_get_ifkey(r->esp_netif), ip_protocol_str[r->ip_protocol],
r->ttl);
if (r->esp_netif) {
printf("%d: Interface: %s, Type: %s, TTL: %u\n", i++, esp_netif_get_ifkey(r->esp_netif),
ip_protocol_str[r->ip_protocol], r->ttl);
}
if (r->instance_name) {
printf(" PTR : %s.%s.%s\n", r->instance_name, r->service_type, r->proto);
}
@ -140,6 +142,27 @@ static void query_mdns_service(const char *service_name, const char *proto)
mdns_query_results_free(results);
}
#if CONFIG_MDNS_PUBLISH_DELEGATE_HOST
static void lookup_mdns_delegated_service(const char *service_name, const char *proto)
{
ESP_LOGI(TAG, "Lookup delegated service: %s.%s.local", service_name, proto);
mdns_result_t *results = NULL;
esp_err_t err = mdns_lookup_delegated_service(NULL, service_name, proto, 20, &results);
if (err) {
ESP_LOGE(TAG, "Lookup Failed: %s", esp_err_to_name(err));
return;
}
if (!results) {
ESP_LOGW(TAG, "No results found!");
return;
}
mdns_print_results(results);
mdns_query_results_free(results);
}
#endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST
static bool check_and_print_result(mdns_search_once_t *search)
{
// Check if any result is available
@ -234,6 +257,9 @@ static void check_button(void)
query_mdns_service("_smb", "_tcp");
query_mdns_service("_ftp", "_tcp");
query_mdns_service("_nfs", "_tcp");
#if CONFIG_MDNS_PUBLISH_DELEGATE_HOST
lookup_mdns_delegated_service("_http", "_tcp");
#endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST
}
old_level = new_level;
}

View File

@ -1,5 +1,6 @@
version: "1.0.8"
version: "1.1.0"
description: mDNS
url: https://github.com/espressif/esp-protocols/tree/master/components/mdns
dependencies:
idf:
version: ">=5.0"

View File

@ -26,7 +26,6 @@ extern "C" {
*/
typedef struct mdns_search_once_s mdns_search_once_t;
typedef enum {
MDNS_EVENT_ENABLE_IP4 = 1 << 1,
MDNS_EVENT_ENABLE_IP6 = 1 << 2,
@ -248,7 +247,6 @@ esp_err_t mdns_service_add_for_host(const char *instance_name, const char *servi
*/
bool mdns_service_exists(const char *service_type, const char *proto, const char *hostname);
/**
* @brief Check whether a service has been added.
*
@ -687,6 +685,24 @@ esp_err_t mdns_query_srv(const char *instance_name, const char *service_type, co
*/
esp_err_t mdns_query_txt(const char *instance_name, const char *service_type, const char *proto, uint32_t timeout, mdns_result_t **result);
/**
* @brief Look up delegated services.
*
* @param instance instance name (NULL for uncertain instance)
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param max_results maximum results to be collected
* @param result pointer to the result of the search
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_lookup_delegated_service(const char *instance, const char *service_type, const char *proto, size_t max_results,
mdns_result_t **result);
/**
* @brief Query mDNS for A record
*

View File

@ -678,7 +678,7 @@ static uint16_t append_fqdn_dots(uint8_t *packet, uint16_t *index, const char *n
char *end = host;
char *start = host;
do {
end = memchr(start, '.', len);
end = memchr(start, '.', host + len - start);
end = end ? end : host + len;
int part_len = end - start;
if (!append_single_str(packet, index, start, part_len)) {
@ -733,6 +733,7 @@ search_next:
//read the destination into name and compare
name.parts = 0;
name.sub = 0;
name.invalid = false;
name.host[0] = 0;
name.service[0] = 0;
name.proto[0] = 0;
@ -1357,7 +1358,7 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
} else if (answer->type == MDNS_TYPE_A) {
if (answer->host == &_mdns_self_host) {
esp_netif_ip_info_t if_ip_info;
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state != PCB_DUP) {
if (!mdns_is_netif_ready(tcpip_if, MDNS_IP_PROTOCOL_V4) && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state != PCB_DUP) {
return 0;
}
if (esp_netif_get_ip_info(_mdns_get_esp_netif(tcpip_if), &if_ip_info)) {
@ -1384,32 +1385,39 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
#if CONFIG_LWIP_IPV6
else if (answer->type == MDNS_TYPE_AAAA) {
if (answer->host == &_mdns_self_host) {
struct esp_ip6_addr if_ip6;
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].state != PCB_DUP) {
struct esp_ip6_addr if_ip6s[NETIF_IPV6_MAX_NUMS];
uint8_t count = 0;
if (!mdns_is_netif_ready(tcpip_if, MDNS_IP_PROTOCOL_V6) && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].state != PCB_DUP) {
return 0;
}
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(tcpip_if), &if_ip6)) {
return 0;
}
if (_ipv6_address_is_zero(if_ip6)) {
return 0;
}
if (_mdns_append_aaaa_record(packet, index, _mdns_server->hostname, (uint8_t *)if_ip6.addr, answer->flush, answer->bye) <= 0) {
return 0;
count = esp_netif_get_all_ip6(_mdns_get_esp_netif(tcpip_if), if_ip6s);
assert(count <= NETIF_IPV6_MAX_NUMS);
for (int i = 0; i < count; i++) {
if (_ipv6_address_is_zero(if_ip6s[i])) {
return 0;
}
if (_mdns_append_aaaa_record(packet, index, _mdns_server->hostname, (uint8_t *)if_ip6s[i].addr,
answer->flush, answer->bye) <= 0) {
return 0;
}
}
if (!_mdns_if_is_dup(tcpip_if)) {
return 1;
return count;
}
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(other_if), &if_ip6)) {
return 1;
mdns_if_t other_if = _mdns_get_other_if(tcpip_if);
struct esp_ip6_addr other_ip6;
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(other_if), &other_ip6)) {
return count;
}
if (_mdns_append_aaaa_record(packet, index, _mdns_server->hostname, (uint8_t *)if_ip6.addr, answer->flush, answer->bye) > 0) {
return 2;
if (_mdns_append_aaaa_record(packet, index, _mdns_server->hostname, (uint8_t *)other_ip6.addr,
answer->flush, answer->bye) > 0) {
return 1 + count;
}
return 1;
return count;
} else if (answer->host != NULL) {
return _mdns_append_host_answer(packet, index, answer->host, ESP_IPADDR_TYPE_V6, answer->flush, answer->bye);
return _mdns_append_host_answer(packet, index, answer->host, ESP_IPADDR_TYPE_V6, answer->flush,
answer->bye);
}
}
#endif
@ -1606,18 +1614,20 @@ static void _mdns_remove_scheduled_answer(mdns_if_t tcpip_if, mdns_ip_protocol_t
while (q) {
if (q->tcpip_if == tcpip_if && q->ip_protocol == ip_protocol && q->distributed) {
mdns_out_answer_t *a = q->answers;
if (a->type == type && a->service == service->service) {
q->answers = q->answers->next;
free(a);
} else {
while (a->next) {
if (a->next->type == type && a->next->service == service->service) {
mdns_out_answer_t *b = a->next;
a->next = b->next;
free(b);
break;
if (a) {
if (a->type == type && a->service == service->service) {
q->answers = q->answers->next;
free(a);
} else {
while (a->next) {
if (a->next->type == type && a->next->service == service->service) {
mdns_out_answer_t *b = a->next;
a->next = b->next;
free(b);
break;
}
a = a->next;
}
a = a->next;
}
}
}
@ -2266,7 +2276,7 @@ static void _mdns_send_bye(mdns_srv_item_t **services, size_t len, bool include_
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb && _mdns_server->interfaces[i].pcbs[j].state == PCB_RUNNING) {
if (mdns_is_netif_ready(i, j) && _mdns_server->interfaces[i].pcbs[j].state == PCB_RUNNING) {
_mdns_pcb_send_bye((mdns_if_t)i, (mdns_ip_protocol_t)j, services, len, include_ip);
}
}
@ -2280,7 +2290,7 @@ static void _mdns_announce_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protoco
{
mdns_pcb_t *_pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
size_t i;
if (_pcb->pcb) {
if (mdns_is_netif_ready(tcpip_if, ip_protocol)) {
if (PCB_STATE_IS_PROBING(_pcb)) {
_mdns_init_pcb_probe(tcpip_if, ip_protocol, services, len, include_ip);
} else if (PCB_STATE_IS_ANNOUNCING(_pcb)) {
@ -2324,7 +2334,7 @@ static void _mdns_probe_all_pcbs(mdns_srv_item_t **services, size_t len, bool pr
uint8_t i, j;
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb) {
if (mdns_is_netif_ready(i, j)) {
mdns_pcb_t *_pcb = &_mdns_server->interfaces[i].pcbs[j];
if (clear_old_probe) {
free(_pcb->probe_services);
@ -2619,7 +2629,7 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)
mdns_pcb_t *_pcb = &_mdns_server->interfaces[q->tcpip_if].pcbs[q->ip_protocol];
if (_pcb->pcb) {
if (mdns_is_netif_ready(q->tcpip_if, q->ip_protocol)) {
if (PCB_STATE_IS_PROBING(_pcb)) {
uint8_t i;
//check if we are probing this service
@ -2820,6 +2830,22 @@ static int _mdns_check_txt_collision(mdns_service_t *service, const uint8_t *dat
return 0;//same
}
static esp_err_t mdns_pcb_deinit_local(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_proto)
{
esp_err_t err = _mdns_pcb_deinit(tcpip_if, ip_proto);
mdns_pcb_t *_pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_proto];
if (_pcb == NULL || err != ESP_OK) {
return err;
}
free(_pcb->probe_services);
_pcb->state = PCB_OFF;
_pcb->probe_ip = false;
_pcb->probe_services = NULL;
_pcb->probe_services_len = 0;
_pcb->probe_running = false;
_pcb->failed_probes = 0;
return ESP_OK;
}
/**
* @brief Set interface as duplicate if another is found on the same subnet
*/
@ -2831,11 +2857,11 @@ static void _mdns_dup_interface(mdns_if_t tcpip_if)
return; // no other interface found
}
for (i = 0; i < MDNS_IP_PROTOCOL_MAX; i++) {
if (_mdns_server->interfaces[other_if].pcbs[i].pcb) {
if (mdns_is_netif_ready(other_if, i)) {
//stop this interface and mark as dup
if (_mdns_server->interfaces[tcpip_if].pcbs[i].pcb) {
if (mdns_is_netif_ready(tcpip_if, i)) {
_mdns_clear_pcb_tx_queue_head(tcpip_if, i);
_mdns_pcb_deinit(tcpip_if, i);
mdns_pcb_deinit_local(tcpip_if, i);
}
_mdns_server->interfaces[tcpip_if].pcbs[i].state = PCB_DUP;
_mdns_announce_pcb(other_if, i, NULL, 0, true);
@ -3058,6 +3084,29 @@ static bool _mdns_name_is_discovery(mdns_name_t *name, uint16_t type)
);
}
/**
* @brief Check if the parsed name is self-hosted, i.e. we should resolve conflicts
*/
static bool _mdns_name_is_selfhosted(mdns_name_t *name)
{
if (_str_null_or_empty(_mdns_server->hostname)) { // self-hostname needs to be defined
return false;
}
// hostname only -- check if selfhosted name
if (_str_null_or_empty(name->service) && _str_null_or_empty(name->proto) &&
strcasecmp(name->host, _mdns_server->hostname) == 0 ) {
return true;
}
// service -- check if selfhosted service
mdns_srv_item_t *srv = _mdns_get_service_item(name->service, name->proto, NULL);
if (srv && strcasecmp(_mdns_server->hostname, srv->service->hostname) == 0) {
return true;
}
return false;
}
/**
* @brief Check if the parsed name is ours (matches service or host name)
*/
@ -3666,7 +3715,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
}
}
}
bool is_selfhosted = _mdns_name_is_selfhosted(name);
if (!_mdns_parse_fqdn(data, data_ptr + MDNS_SRV_FQDN_OFFSET, name, len)) {
continue;//error
}
@ -3694,6 +3743,9 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
_mdns_remove_scheduled_answer(packet->tcpip_if, packet->ip_protocol, type, service);
continue;
}
if (!is_selfhosted) {
continue;
}
//detect collision (-1=won, 0=none, 1=lost)
int col = 0;
if (mdns_class > 1) {
@ -3784,6 +3836,9 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
_mdns_remove_parsed_question(parsed_packet, type, service);
continue;
}
if (!_mdns_name_is_selfhosted(name)) {
continue;
}
//detect collision (-1=won, 0=none, 1=lost)
int col = 0;
if (mdns_class > 1) {
@ -3818,6 +3873,9 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
_mdns_remove_parsed_question(parsed_packet, type, NULL);
continue;
}
if (!_mdns_name_is_selfhosted(name)) {
continue;
}
//detect collision (-1=won, 0=none, 1=lost)
int col = 0;
if (mdns_class > 1) {
@ -3868,6 +3926,9 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
_mdns_remove_parsed_question(parsed_packet, type, NULL);
continue;
}
if (!_mdns_name_is_selfhosted(name)) {
continue;
}
//detect collision (-1=won, 0=none, 1=lost)
int col = 0;
if (mdns_class > 1) {
@ -3940,8 +4001,9 @@ clear_rx_packet:
*/
void _mdns_enable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (!_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
if (!mdns_is_netif_ready(tcpip_if, ip_protocol)) {
if (_mdns_pcb_init(tcpip_if, ip_protocol)) {
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
return;
}
}
@ -3955,9 +4017,9 @@ void _mdns_disable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
_mdns_clean_netif_ptr(tcpip_if);
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
if (mdns_is_netif_ready(tcpip_if, ip_protocol)) {
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
_mdns_pcb_deinit(tcpip_if, ip_protocol);
mdns_pcb_deinit_local(tcpip_if, ip_protocol);
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if != MDNS_MAX_INTERFACES && _mdns_server->interfaces[other_if].pcbs[ip_protocol].state == PCB_DUP) {
_mdns_server->interfaces[other_if].pcbs[ip_protocol].state = PCB_OFF;
@ -4625,7 +4687,7 @@ static mdns_tx_packet_t *_mdns_create_search_packet(mdns_search_once_t *search,
static void _mdns_search_send_pcb(mdns_search_once_t *search, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_tx_packet_t *packet = NULL;
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb && _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state > PCB_INIT) {
if (mdns_is_netif_ready(tcpip_if, ip_protocol) && _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state > PCB_INIT) {
packet = _mdns_create_search_packet(search, tcpip_if, ip_protocol);
if (!packet) {
return;
@ -5348,16 +5410,10 @@ esp_err_t mdns_init(void)
s_esp_netifs[i].netif = NULL;
}
_mdns_server->lock = xSemaphoreCreateMutex();
if (!_mdns_server->lock) {
err = ESP_ERR_NO_MEM;
goto free_server;
}
_mdns_server->action_queue = xQueueCreate(MDNS_ACTION_QUEUE_LEN, sizeof(mdns_action_t *));
if (!_mdns_server->action_queue) {
err = ESP_ERR_NO_MEM;
goto free_lock;
goto free_server;
}
_mdns_server->action_sema = xSemaphoreCreateBinary();
@ -5424,8 +5480,6 @@ free_event_handlers:
vSemaphoreDelete(_mdns_server->action_sema);
free_queue:
vQueueDelete(_mdns_server->action_queue);
free_lock:
vSemaphoreDelete(_mdns_server->lock);
free_server:
free(_mdns_server);
_mdns_server = NULL;
@ -5447,7 +5501,7 @@ void mdns_free(void)
_mdns_service_task_stop();
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
_mdns_pcb_deinit(i, j);
mdns_pcb_deinit_local(i, j);
}
}
free((char *)_mdns_server->hostname);
@ -5473,7 +5527,6 @@ void mdns_free(void)
free(h);
}
vSemaphoreDelete(_mdns_server->action_sema);
vSemaphoreDelete(_mdns_server->lock);
free(_mdns_server);
_mdns_server = NULL;
}
@ -5685,6 +5738,131 @@ bool mdns_service_exists_with_instance(const char *instance, const char *service
return _mdns_get_service_item_instance(instance, service_type, proto, hostname) != NULL;
}
static mdns_txt_item_t *_copy_mdns_txt_items(mdns_txt_linked_item_t *items, uint8_t **txt_value_len, size_t *txt_count)
{
mdns_txt_item_t *ret = NULL;
size_t ret_index = 0;
for (mdns_txt_linked_item_t *tmp = items; tmp != NULL; tmp = tmp->next) {
ret_index++;
}
*txt_count = ret_index;
ret = (mdns_txt_item_t *)calloc(ret_index, sizeof(mdns_txt_item_t));
*txt_value_len = (uint8_t *)calloc(ret_index, sizeof(uint8_t));
if (!ret || !(*txt_value_len)) {
HOOK_MALLOC_FAILED;
goto handle_error;
}
ret_index = 0;
for (mdns_txt_linked_item_t *tmp = items; tmp != NULL; tmp = tmp->next) {
size_t key_len = strlen(tmp->key);
char *key = (char *)malloc(key_len + 1);
if (!key) {
HOOK_MALLOC_FAILED;
goto handle_error;
}
memcpy(key, tmp->key, key_len);
key[key_len] = 0;
ret[ret_index].key = key;
char *value = (char *)malloc(tmp->value_len + 1);
if (!value) {
HOOK_MALLOC_FAILED;
goto handle_error;
}
memcpy(value, tmp->value, tmp->value_len);
value[tmp->value_len] = 0;
ret[ret_index].value = value;
(*txt_value_len)[ret_index] = tmp->value_len;
ret_index++;
}
return ret;
handle_error:
for (size_t y = 0; y < ret_index + 1; y++) {
mdns_txt_item_t *t = &ret[y];
free((char *)t->key);
free((char *)t->value);
}
free(*txt_value_len);
free(ret);
return NULL;
}
static mdns_ip_addr_t *_copy_delegated_host_address_list(char *hostname)
{
mdns_host_item_t *host = _mdns_host_list;
while (host) {
if (strcasecmp(host->hostname, hostname) == 0) {
return copy_address_list(host->address_list);
}
}
return NULL;
}
static mdns_result_t *_mdns_lookup_delegated_service(const char *instance, const char *service, const char *proto, size_t max_results)
{
if (_str_null_or_empty(service) || _str_null_or_empty(proto)) {
return NULL;
}
mdns_result_t *results = NULL;
size_t num_results = 0;
mdns_srv_item_t *s = _mdns_server->services;
while (s) {
mdns_service_t *srv = s->service;
if (srv && srv->hostname && (_str_null_or_empty(_mdns_server->hostname) || strcmp(_mdns_server->hostname, srv->hostname) != 0)) {
if (!strcasecmp(srv->service, service) && !strcasecmp(srv->proto, proto) &&
(_str_null_or_empty(instance) || _mdns_instance_name_match(srv->instance, instance))) {
mdns_result_t *item = (mdns_result_t *)malloc(sizeof(mdns_result_t));
if (!item) {
HOOK_MALLOC_FAILED;
goto handle_error;
}
item->next = results;
results = item;
item->esp_netif = NULL;
item->ttl = UINT32_MAX;
item->ip_protocol = MDNS_IP_PROTOCOL_MAX;
item->instance_name = strndup(srv->instance, MDNS_NAME_BUF_LEN - 1);
if (!item->instance_name) {
HOOK_MALLOC_FAILED;
goto handle_error;
}
item->service_type = strndup(srv->service, MDNS_NAME_BUF_LEN - 1);
if (!item->service_type) {
HOOK_MALLOC_FAILED;
goto handle_error;
}
item->proto = strndup(srv->proto, MDNS_NAME_BUF_LEN - 1);
if (!item->proto) {
HOOK_MALLOC_FAILED;
goto handle_error;
}
item->hostname = strndup(srv->hostname, MDNS_NAME_BUF_LEN - 1);
if (!item->hostname) {
HOOK_MALLOC_FAILED;
goto handle_error;
}
item->port = srv->port;
item->txt = _copy_mdns_txt_items(srv->txt, &(item->txt_value_len), &(item->txt_count));
item->addr = _copy_delegated_host_address_list(item->hostname);
if (!item->addr) {
goto handle_error;
}
if (num_results < max_results) {
num_results++;
}
if (num_results >= max_results) {
break;
}
}
}
s = s->next;
}
return results;
handle_error:
mdns_query_results_free(results);
return NULL;
}
esp_err_t mdns_service_port_set_for_host(const char *instance, const char *service, const char *proto, const char *hostname, uint16_t port)
{
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) || !port) {
@ -6156,6 +6334,21 @@ esp_err_t mdns_query_txt(const char *instance, const char *service, const char *
return mdns_query(instance, service, proto, MDNS_TYPE_TXT, timeout, 1, result);
}
esp_err_t mdns_lookup_delegated_service(const char *instance, const char *service, const char *proto, size_t max_results,
mdns_result_t **result)
{
if (!_mdns_server) {
return ESP_ERR_INVALID_STATE;
}
if (!result || _str_null_or_empty(service) || _str_null_or_empty(proto)) {
return ESP_ERR_INVALID_ARG;
}
MDNS_SERVICE_LOCK();
*result = _mdns_lookup_delegated_service(instance, service, proto, max_results);
MDNS_SERVICE_UNLOCK();
return ESP_OK;
}
esp_err_t mdns_query_a(const char *name, uint32_t timeout, esp_ip4_addr_t *addr)
{
mdns_result_t *result = NULL;

View File

@ -21,16 +21,26 @@
#include "mdns_networking.h"
#include "esp_netif_net_stack.h"
extern mdns_server_t *_mdns_server;
/*
* MDNS Server Networking
*
*/
static const char *TAG = "mdns_networking";
enum interface_protocol {
PROTO_IPV4 = 1 << MDNS_IP_PROTOCOL_V4,
PROTO_IPV6 = 1 << MDNS_IP_PROTOCOL_V6
};
typedef struct interfaces {
bool ready;
int proto;
} interfaces_t;
static interfaces_t s_interfaces[MDNS_MAX_INTERFACES];
static struct udp_pcb *_pcb_main = NULL;
static const char *TAG = "mdns_networking";
static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip_addr_t *raddr, uint16_t rport);
/**
@ -53,7 +63,7 @@ static esp_err_t _udp_pcb_main_init(void)
_pcb_main->mcast_ttl = 255;
_pcb_main->remote_port = MDNS_SERVICE_PORT;
ip_addr_copy(_pcb_main->remote_ip, *(IP_ANY_TYPE));
udp_recv(_pcb_main, &_udp_recv, _mdns_server);
udp_recv(_pcb_main, &_udp_recv, NULL);
return ESP_OK;
}
@ -168,29 +178,26 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
//lwip does not return the proper pcb if you have more than one for the same multicast address (but different interfaces)
struct netif *netif = NULL;
struct udp_pcb *pcb = NULL;
bool found = false;
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
pcb = _mdns_server->interfaces[i].pcbs[packet->ip_protocol].pcb;
netif = esp_netif_get_netif_impl(_mdns_get_esp_netif(i));
if (pcb && netif && netif == ip_current_input_netif ()) {
if (s_interfaces[i].proto && netif && netif == ip_current_input_netif ()) {
if (packet->src.type == IPADDR_TYPE_V4) {
#if CONFIG_LWIP_IPV6
if ((packet->src.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr) != (netif->ip_addr.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr)) {
#else
if ((packet->src.u_addr.ip4.addr & netif->netmask.addr) != (netif->ip_addr.addr & netif->netmask.addr)) {
#endif //packet source is not in the same subnet
pcb = NULL;
break;
}
}
packet->tcpip_if = i;
found = true;
break;
}
pcb = NULL;
}
if (!pcb || !_mdns_server || !_mdns_server->action_queue
|| _mdns_send_rx_action(packet) != ESP_OK) {
if (!found || _mdns_send_rx_action(packet) != ESP_OK) {
pbuf_free(this_pb);
free(packet);
}
@ -198,6 +205,12 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
}
bool mdns_is_netif_ready(mdns_if_t netif, mdns_ip_protocol_t ip_proto)
{
return s_interfaces[netif].ready &&
s_interfaces[netif].proto & (ip_proto == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
}
/**
* @brief Check if any of the interfaces is up
*/
@ -206,7 +219,7 @@ static bool _udp_pcb_is_in_use(void)
int i, p;
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (p = 0; p < MDNS_IP_PROTOCOL_MAX; p++) {
if (_mdns_server->interfaces[i].pcbs[p].pcb) {
if (mdns_is_netif_ready(i, p)) {
return true;
}
}
@ -219,19 +232,9 @@ static bool _udp_pcb_is_in_use(void)
*/
static void _udp_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (!_mdns_server) {
return;
}
mdns_pcb_t *_pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
if (_pcb->pcb) {
free(_pcb->probe_services);
_pcb->state = PCB_OFF;
_pcb->pcb = NULL;
_pcb->probe_ip = false;
_pcb->probe_services = NULL;
_pcb->probe_services_len = 0;
_pcb->probe_running = false;
_pcb->failed_probes = 0;
s_interfaces[tcpip_if].proto &= ~(ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
if (s_interfaces[tcpip_if].proto == 0) {
s_interfaces[tcpip_if].ready = false;
_udp_join_group(tcpip_if, ip_protocol, false);
if (!_udp_pcb_is_in_use()) {
_udp_pcb_main_deinit();
@ -244,7 +247,7 @@ static void _udp_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
*/
static esp_err_t _udp_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (!_mdns_server || _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
if (mdns_is_netif_ready(tcpip_if, ip_protocol)) {
return ESP_ERR_INVALID_STATE;
}
@ -257,9 +260,9 @@ static esp_err_t _udp_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protoco
if (err) {
return err;
}
s_interfaces[tcpip_if].proto |= (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
s_interfaces[tcpip_if].ready = true;
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = _pcb_main;
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
return ESP_OK;
}
@ -323,14 +326,13 @@ static err_t _mdns_udp_pcb_write_api(struct tcpip_api_call_data *api_call_msg)
{
void *nif = NULL;
mdns_api_call_t *msg = (mdns_api_call_t *)api_call_msg;
mdns_pcb_t *_pcb = &_mdns_server->interfaces[msg->tcpip_if].pcbs[msg->ip_protocol];
nif = esp_netif_get_netif_impl(_mdns_get_esp_netif(msg->tcpip_if));
if (!nif) {
if (!nif || !mdns_is_netif_ready(msg->tcpip_if, msg->ip_protocol) || _pcb_main == NULL) {
pbuf_free(msg->pbt);
msg->err = ERR_IF;
return ERR_IF;
}
esp_err_t err = udp_sendto_if (_pcb->pcb, msg->pbt, msg->ip, msg->port, (struct netif *)nif);
esp_err_t err = udp_sendto_if (_pcb_main, msg->pbt, msg->ip, msg->port, (struct netif *)nif);
pbuf_free(msg->pbt);
msg->err = err;
return err;

View File

@ -27,7 +27,17 @@
#include <net/if.h>
#endif
extern mdns_server_t *_mdns_server;
enum interface_protocol {
PROTO_IPV4 = 1 << MDNS_IP_PROTOCOL_V4,
PROTO_IPV6 = 1 << MDNS_IP_PROTOCOL_V6
};
typedef struct interfaces {
int sock;
int proto;
} interfaces_t;
static interfaces_t s_interfaces[MDNS_MAX_INTERFACES];
static const char *TAG = "mdns_networking";
static bool s_run_sock_recv_task = false;
@ -47,28 +57,22 @@ struct pbuf {
#define s6_addr32 un.u32_addr
#endif // CONFIG_IDF_TARGET_LINUX
static void __attribute__((constructor)) ctor_networking_socket(void)
{
for (int i = 0; i < sizeof(s_interfaces) / sizeof(s_interfaces[0]); ++i) {
s_interfaces[i].sock = -1;
s_interfaces[i].proto = 0;
}
}
static void delete_socket(int sock)
{
close(sock);
}
static struct udp_pcb *sock_to_pcb(int sock)
bool mdns_is_netif_ready(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (sock < 0) {
return NULL;
}
// Note: sock=0 is a valid descriptor, so save it as +1 ("1" is a valid pointer)
intptr_t sock_plus_one = sock + 1;
return (struct udp_pcb *)sock_plus_one;
}
static int pcb_to_sock(struct udp_pcb *pcb)
{
if (pcb == NULL) {
return -1;
}
intptr_t sock_plus_one = (intptr_t)pcb;
return sock_plus_one - 1;
return s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
}
void *_mdns_get_packet_data(mdns_rx_packet_t *packet)
@ -90,24 +94,18 @@ void _mdns_packet_free(mdns_rx_packet_t *packet)
esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
struct udp_pcb *pcb = _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb;
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = NULL;
if (_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb == NULL &&
_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb == NULL) {
// if the interface for both protocol uninitialized, close the interface socket
int sock = pcb_to_sock(pcb);
if (sock >= 0) {
delete_socket(sock);
s_interfaces[tcpip_if].proto &= ~(ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
if (s_interfaces[tcpip_if].proto == 0) {
// if the interface for both protocols uninitialized, close the interface socket
if (s_interfaces[tcpip_if].sock >= 0) {
delete_socket(s_interfaces[tcpip_if].sock);
}
}
for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (int j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb)
// If any of the interfaces/protocol initialized
{
return ESP_OK;
}
if (s_interfaces[i].sock >= 0) {
// If any of the interfaces initialized
return ESP_OK;
}
}
@ -191,7 +189,10 @@ static inline size_t espaddr_to_inet(const esp_ip_addr_t *addr, const uint16_t p
size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const esp_ip_addr_t *ip, uint16_t port, uint8_t *data, size_t len)
{
int sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb);
if (!(s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6))) {
return 0;
}
int sock = s_interfaces[tcpip_if].sock;
if (sock < 0) {
return 0;
}
@ -250,12 +251,10 @@ void sock_recv_task(void *arg)
FD_ZERO(&rfds);
int max_sock = -1;
for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (int j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
int sock = pcb_to_sock(_mdns_server->interfaces[i].pcbs[j].pcb);
if (sock >= 0) {
FD_SET(sock, &rfds);
max_sock = MAX(max_sock, sock);
}
int sock = s_interfaces[i].sock;
if (sock >= 0) {
FD_SET(sock, &rfds);
max_sock = MAX(max_sock, sock);
}
}
if (max_sock < 0) {
@ -270,11 +269,7 @@ void sock_recv_task(void *arg)
break;
} else if (s > 0) {
for (int tcpip_if = 0; tcpip_if < MDNS_MAX_INTERFACES; tcpip_if++) {
// Both protocols share once socket
int sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb);
if (sock < 0) {
sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb);
}
int sock = s_interfaces[tcpip_if].sock;
if (sock < 0) {
continue;
}
@ -323,7 +318,7 @@ void sock_recv_task(void *arg)
packet->dest.type = packet->src.type;
packet->ip_protocol =
packet->src.type == ESP_IPADDR_TYPE_V4 ? MDNS_IP_PROTOCOL_V4 : MDNS_IP_PROTOCOL_V6;
if (!_mdns_server || !_mdns_server->action_queue || _mdns_send_rx_action(packet) != ESP_OK) {
if (_mdns_send_rx_action(packet) != ESP_OK) {
ESP_LOGE(TAG, "_mdns_send_rx_action failed!");
free(packet->pb->payload);
free(packet->pb);
@ -344,39 +339,43 @@ static void mdns_networking_init(void)
}
}
static struct udp_pcb *create_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static bool create_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
return _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb;
if (s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6)) {
return true;
}
mdns_ip_protocol_t other_ip_proto = ip_protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_IP_PROTOCOL_V6 : MDNS_IP_PROTOCOL_V4;
int sock = s_interfaces[tcpip_if].sock;
esp_netif_t *netif = _mdns_get_esp_netif(tcpip_if);
if (_mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb) {
struct udp_pcb *other_pcb = _mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb;
int err = join_mdns_multicast_group(pcb_to_sock(other_pcb), netif, ip_protocol);
if (sock >= 0) {
mdns_ip_protocol_t other_ip_proto = ip_protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_IP_PROTOCOL_V6 : MDNS_IP_PROTOCOL_V4;
int err = join_mdns_multicast_group(sock, netif, other_ip_proto);
if (err < 0) {
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
return NULL;
return false;
}
return other_pcb;
s_interfaces[tcpip_if].proto |= (other_ip_proto == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
return true;
}
int sock = create_socket(netif);
sock = create_socket(netif);
if (sock < 0) {
ESP_LOGE(TAG, "Failed to create the socket!");
return NULL;
return false;
}
int err = join_mdns_multicast_group(sock, netif, ip_protocol);
if (err < 0) {
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
}
return sock_to_pcb(sock);
s_interfaces[tcpip_if].proto |= (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
s_interfaces[tcpip_if].sock = sock;
return true;
}
esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
ESP_LOGI(TAG, "_mdns_pcb_init(tcpip_if=%d, ip_protocol=%d)", tcpip_if, ip_protocol);
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = create_pcb(tcpip_if, ip_protocol);
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
if (!create_pcb(tcpip_if, ip_protocol)) {
return ESP_FAIL;
}
mdns_networking_init();
return ESP_OK;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -19,6 +19,8 @@
*/
esp_err_t _mdns_send_rx_action(mdns_rx_packet_t *packet);
bool mdns_is_netif_ready(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
/**
* @brief Start PCB
*/

View File

@ -33,6 +33,12 @@
#endif
#define MDNS_MAX_PREDEF_INTERFACES (CONFIG_MDNS_PREDEF_NETIF_STA + CONFIG_MDNS_PREDEF_NETIF_AP + CONFIG_MDNS_PREDEF_NETIF_ETH)
#ifdef CONFIG_LWIP_IPV6_NUM_ADDRESSES
#define NETIF_IPV6_MAX_NUMS CONFIG_LWIP_IPV6_NUM_ADDRESSES
#else
#define NETIF_IPV6_MAX_NUMS 3
#endif
/** Number of configured interfaces */
#if MDNS_MAX_PREDEF_INTERFACES > CONFIG_MDNS_MAX_INTERFACES
#warning Number of configured interfaces is less then number of predefined interfaces. Please update CONFIG_MDNS_MAX_INTERFACES.
@ -341,7 +347,6 @@ typedef struct mdns_tx_packet_s {
typedef struct {
mdns_pcb_state_t state;
struct udp_pcb *pcb;
mdns_srv_item_t **probe_services;
uint8_t probe_services_len;
uint8_t probe_ip;
@ -382,7 +387,6 @@ typedef struct mdns_server_s {
const char *hostname;
const char *instance;
mdns_srv_item_t *services;
SemaphoreHandle_t lock;
QueueHandle_t action_queue;
SemaphoreHandle_t action_sema;
mdns_tx_packet_t *tx_queue_head;

View File

@ -5,3 +5,7 @@ set(EXTRA_COMPONENT_DIRS "../..")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main esp_netif_linux)
project(mdns_host)
# Enable sanitizers for mdns implementation
idf_component_get_property(mdns mdns COMPONENT_LIB)
target_link_options(${mdns} INTERFACE -fsanitize=address -fsanitize=undefined)

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