forked from espressif/esp-protocols
Compare commits
187 Commits
websocket-
...
docs/docs_
Author | SHA1 | Date | |
---|---|---|---|
a3e8421de8 | |||
3bf0511938 | |||
319fce018e | |||
44bae24c78 | |||
d047ff569c | |||
02be2b76f8 | |||
1c850ddacf | |||
9ae88aab48 | |||
c6db3ea84c | |||
b23eedac3a | |||
1407dfc2e7 | |||
34c6f52f70 | |||
c674b8855d | |||
256389613f | |||
2865255ec0 | |||
7b2470ddd6 | |||
dda2722563 | |||
36db37ea2b | |||
4f013e3522 | |||
231392d0c6 | |||
9fb01ca534 | |||
d464ed7d30 | |||
b94a211e4b | |||
73f2800b59 | |||
e00e056162 | |||
1b134486db | |||
7ba1085e9f | |||
3bdb2067e0 | |||
1d6888445d | |||
d68624ec4f | |||
d4825f5c53 | |||
de1480a072 | |||
b9b4a75000 | |||
cc259aa035 | |||
91134f10ff | |||
fb8a2f0198 | |||
b87bef52e5 | |||
28813148b2 | |||
ae38f27997 | |||
d0c9070715 | |||
a8339e4618 | |||
12cfcb5aed | |||
2cfffb056e | |||
0247926219 | |||
05fff94b91 | |||
8958d5e37c | |||
f71192b876 | |||
f9b47900f2 | |||
0e215b118f | |||
dc8b916561 | |||
a01096f621 | |||
3de4727385 | |||
59053b8c98 | |||
2956477353 | |||
1d9b6f7e90 | |||
6b684ceb0f | |||
5304a6ec0e | |||
c7f20ee98e | |||
7d47ec3b6b | |||
e4c8a5932c | |||
b56b1c577b | |||
4e212c31fe | |||
9a7bd90ad9 | |||
4314c78ca0 | |||
457f8335bb | |||
42565ff5d7 | |||
6e2bb518fd | |||
2180ab17d8 | |||
ac5d43882b | |||
3f0262dfe5 | |||
74787c9aa8 | |||
045009bb82 | |||
79c11e9ecd | |||
c73c797595 | |||
3330b96b10 | |||
1547aa8c03 | |||
1ca139109a | |||
55c1223a1e | |||
0643613eee | |||
55dc56462f | |||
698fb3ae00 | |||
23a537b19b | |||
aee016d6e4 | |||
f1ae14f263 | |||
65c0e0e195 | |||
f71f61ff0a | |||
652314e73d | |||
71a2388acb | |||
ebc36a3519 | |||
5097065a22 | |||
193ac643e4 | |||
945bd17701 | |||
9d45d505d5 | |||
96fcbc0694 | |||
6b4767cba0 | |||
f148c98b13 | |||
06103e4bb4 | |||
c6fc267e5f | |||
52b7f001a2 | |||
cf504ec900 | |||
ab2e08f96c | |||
511ed541b8 | |||
8d0e2aab6b | |||
a02bf05eed | |||
85a2e25093 | |||
a9b5e66d0f | |||
988b3f9905 | |||
53b59332dc | |||
bf84ae940a | |||
a89a0ab7a3 | |||
fe536e476c | |||
afafcb7c24 | |||
55b4775ca8 | |||
1c6c610f20 | |||
9b48b0a5e0 | |||
25ac2d98c6 | |||
ce175df376 | |||
9d9d0db1ee | |||
b704aaa33b | |||
7a21db23ad | |||
fcd6f0bb14 | |||
52d7458b99 | |||
56cb58ced7 | |||
77a7538a02 | |||
c8d0a13f0e | |||
582f5b5ff6 | |||
06dd536d52 | |||
e66b19c414 | |||
0ad6cad8b2 | |||
ffa13e4b90 | |||
0fc1fc6b23 | |||
f1d1d79daf | |||
36d0d32b35 | |||
3bf488eb86 | |||
061885ad23 | |||
ab70791625 | |||
62cb235aa9 | |||
04c711f757 | |||
467fec5c9b | |||
5193ebc6ea | |||
3498e86d8b | |||
07a347f907 | |||
d9c9681094 | |||
7310a7a0bc | |||
accf9244ca | |||
290197c210 | |||
b8d1e58778 | |||
cc4d33d871 | |||
ef0e48a678 | |||
187ef7676e | |||
a8714730fb | |||
d2f519f9e5 | |||
a045c1c885 | |||
543521a220 | |||
85be67e708 | |||
5b1b2cce75 | |||
1029078541 | |||
0015e5411c | |||
65b64e1fc1 | |||
d07237b2ce | |||
3c65fde2a7 | |||
35833d2730 | |||
bbb4b7e686 | |||
64e31dae48 | |||
63ce3a5d59 | |||
5dd138c883 | |||
088f7ac3f8 | |||
e079f8ba98 | |||
ff2b0734ea | |||
330332a0fb | |||
48c157bc46 | |||
98bf3efeb6 | |||
ae8479c77e | |||
444fae9066 | |||
bb4c002841 | |||
656ab21c9b | |||
2099434b3f | |||
8f00fc182a | |||
d74c296182 | |||
c4e85bd099 | |||
85ba60e405 | |||
89e1bd27b3 | |||
341fcb0f40 | |||
469f953b28 | |||
381eb314dc | |||
1ffc20c8e3 | |||
3456781494 |
140
.flake8
Normal file
140
.flake8
Normal file
@ -0,0 +1,140 @@
|
||||
[flake8]
|
||||
|
||||
select =
|
||||
# Full lists are given in order to suppress all errors from other plugins
|
||||
# Full list of pyflakes error codes:
|
||||
F401, # module imported but unused
|
||||
F402, # import module from line N shadowed by loop variable
|
||||
F403, # 'from module import *' used; unable to detect undefined names
|
||||
F404, # future import(s) name after other statements
|
||||
F405, # name may be undefined, or defined from star imports: module
|
||||
F406, # 'from module import *' only allowed at module level
|
||||
F407, # an undefined __future__ feature name was imported
|
||||
F601, # dictionary key name repeated with different values
|
||||
F602, # dictionary key variable name repeated with different values
|
||||
F621, # too many expressions in an assignment with star-unpacking
|
||||
F622, # two or more starred expressions in an assignment (a, *b, *c = d)
|
||||
F631, # assertion test is a tuple, which are always True
|
||||
F701, # a break statement outside of a while or for loop
|
||||
F702, # a continue statement outside of a while or for loop
|
||||
F703, # a continue statement in a finally block in a loop
|
||||
F704, # a yield or yield from statement outside of a function
|
||||
F705, # a return statement with arguments inside a generator
|
||||
F706, # a return statement outside of a function/method
|
||||
F707, # an except: block as not the last exception handler
|
||||
F721, F722, # doctest syntax error syntax error in forward type annotation
|
||||
F811, # redefinition of unused name from line N
|
||||
F812, # list comprehension redefines name from line N
|
||||
F821, # undefined name name
|
||||
F822, # undefined name name in __all__
|
||||
F823, # local variable name referenced before assignment
|
||||
F831, # duplicate argument name in function definition
|
||||
F841, # local variable name is assigned to but never used
|
||||
F901, # raise NotImplemented should be raise NotImplementedError
|
||||
|
||||
# Full list of pycodestyle violations:
|
||||
E101, # indentation contains mixed spaces and tabs
|
||||
E111, # indentation is not a multiple of four
|
||||
E112, # expected an indented block
|
||||
E113, # unexpected indentation
|
||||
E114, # indentation is not a multiple of four (comment)
|
||||
E115, # expected an indented block (comment)
|
||||
E116, # unexpected indentation (comment)
|
||||
E121, # continuation line under-indented for hanging indent
|
||||
E122, # continuation line missing indentation or outdented
|
||||
E123, # closing bracket does not match indentation of opening bracket's line
|
||||
E124, # closing bracket does not match visual indentation
|
||||
E125, # continuation line with same indent as next logical line
|
||||
E126, # continuation line over-indented for hanging indent
|
||||
E127, # continuation line over-indented for visual indent
|
||||
E128, # continuation line under-indented for visual indent
|
||||
E129, # visually indented line with same indent as next logical line
|
||||
E131, # continuation line unaligned for hanging indent
|
||||
E133, # closing bracket is missing indentation
|
||||
E201, # whitespace after '('
|
||||
E202, # whitespace before ')'
|
||||
E203, # whitespace before ':'
|
||||
E211, # whitespace before '('
|
||||
E221, # multiple spaces before operator
|
||||
E222, # multiple spaces after operator
|
||||
E223, # tab before operator
|
||||
E224, # tab after operator
|
||||
E225, # missing whitespace around operator
|
||||
E226, # missing whitespace around arithmetic operator
|
||||
E227, # missing whitespace around bitwise or shift operator
|
||||
E228, # missing whitespace around modulo operator
|
||||
E231, # missing whitespace after ',', ';', or ':'
|
||||
E241, # multiple spaces after ','
|
||||
E242, # tab after ','
|
||||
E251, # unexpected spaces around keyword / parameter equals
|
||||
E261, # at least two spaces before inline comment
|
||||
E262, # inline comment should start with '# '
|
||||
E265, # block comment should start with '# '
|
||||
E266, # too many leading '#' for block comment
|
||||
E271, # multiple spaces after keyword
|
||||
E272, # multiple spaces before keyword
|
||||
E273, # tab after keyword
|
||||
E274, # tab before keyword
|
||||
E275, # missing whitespace after keyword
|
||||
E301, # expected 1 blank line, found 0
|
||||
E302, # expected 2 blank lines, found 0
|
||||
E303, # too many blank lines
|
||||
E304, # blank lines found after function decorator
|
||||
E305, # expected 2 blank lines after end of function or class
|
||||
E306, # expected 1 blank line before a nested definition
|
||||
E401, # multiple imports on one line
|
||||
E402, # module level import not at top of file
|
||||
E501, # line too long (82 > 79 characters)
|
||||
E502, # the backslash is redundant between brackets
|
||||
E701, # multiple statements on one line (colon)
|
||||
E702, # multiple statements on one line (semicolon)
|
||||
E703, # statement ends with a semicolon
|
||||
E704, # multiple statements on one line (def)
|
||||
E711, # comparison to None should be 'if cond is None:'
|
||||
E712, # comparison to True should be 'if cond is True:' or 'if cond:'
|
||||
E713, # test for membership should be 'not in'
|
||||
E714, # test for object identity should be 'is not'
|
||||
E721, # do not compare types, use 'isinstance()'
|
||||
E722, # do not use bare except, specify exception instead
|
||||
E731, # do not assign a lambda expression, use a def
|
||||
E741, # do not use variables named 'l', 'O', or 'I'
|
||||
E742, # do not define classes named 'l', 'O', or 'I'
|
||||
E743, # do not define functions named 'l', 'O', or 'I'
|
||||
E901, # SyntaxError or IndentationError
|
||||
E902, # IOError
|
||||
W191, # indentation contains tabs
|
||||
W291, # trailing whitespace
|
||||
W292, # no newline at end of file
|
||||
W293, # blank line contains whitespace
|
||||
W391, # blank line at end of file
|
||||
W503, # line break before binary operator
|
||||
W504, # line break after binary operator
|
||||
W505, # doc line too long (82 > 79 characters)
|
||||
W601, # .has_key() is deprecated, use 'in'
|
||||
W602, # deprecated form of raising exception
|
||||
W603, # '<>' is deprecated, use '!='
|
||||
W604, # backticks are deprecated, use 'repr()'
|
||||
W605, # invalid escape sequence 'x'
|
||||
W606, # 'async' and 'await' are reserved keywords starting with Python 3.7
|
||||
|
||||
# Full list of flake8 violations
|
||||
E999, # failed to compile a file into an Abstract Syntax Tree for the plugins that require it
|
||||
|
||||
# Full list of mccabe violations
|
||||
C901 # complexity value provided by the user
|
||||
|
||||
ignore =
|
||||
E221, # multiple spaces before operator
|
||||
E231, # missing whitespace after ',', ';', or ':'
|
||||
E241, # multiple spaces after ','
|
||||
W503, # line break before binary operator
|
||||
W504 # line break after binary operator
|
||||
|
||||
max-line-length = 160
|
||||
|
||||
show_source = True
|
||||
|
||||
statistics = True
|
||||
|
||||
exclude =
|
||||
components/asio/docs/conf_common.py
|
2
.git-blame-ignore-revs
Normal file
2
.git-blame-ignore-revs
Normal file
@ -0,0 +1,2 @@
|
||||
# Formating according pre-commit hooks
|
||||
945bd177011d984b705daee9b895f88212292a42
|
92
.github/workflows/gcov_analyzer.yml
vendored
Normal file
92
.github/workflows/gcov_analyzer.yml
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
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'
|
35
.github/workflows/host-test.yml
vendored
35
.github/workflows/host-test.yml
vendored
@ -3,16 +3,15 @@ name: Host test
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
host_test:
|
||||
name: Build and Test on Host
|
||||
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
|
||||
@ -26,11 +25,8 @@ jobs:
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8
|
||||
export LWIP_PATH=`pwd`/${{ env.lwip }}
|
||||
export LWIP_CONTRIB_PATH=`pwd`/${{ env.lwip_contrib }}
|
||||
wget --no-verbose ${lwip_uri}/${lwip}.zip
|
||||
unzip -oq ${lwip}.zip
|
||||
wget --no-verbose ${lwip_uri}/${lwip_contrib}.zip
|
||||
unzip -oq ${lwip_contrib}.zip
|
||||
. ${IDF_PATH}/export.sh
|
||||
$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
|
||||
@ -42,3 +38,26 @@ jobs:
|
||||
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
|
||||
|
40
.github/workflows/pre_commit_check.yml
vendored
Normal file
40
.github/workflows/pre_commit_check.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
name: Check pre-commit rules
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
pre_commit_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Fetch head and base refs
|
||||
# This is necessary for pre-commit to check the changes in the PR branch
|
||||
run: |
|
||||
git fetch origin ${{ github.base_ref }}:base_ref
|
||||
git fetch origin pull/${{ github.event.pull_request.number }}/head:pr_ref
|
||||
- name: Set up Python environment
|
||||
uses: actions/setup-python@master
|
||||
with:
|
||||
python-version: v3.7
|
||||
- name: Install python packages
|
||||
run: |
|
||||
pip install pre-commit
|
||||
pre-commit install-hooks
|
||||
- name: Run pre-commit and check for any changes
|
||||
run: |
|
||||
echo "Commits being checked:"
|
||||
git log --oneline --no-decorate base_ref..pr_ref
|
||||
echo ""
|
||||
if ! pre-commit run --from-ref base_ref --to-ref pr_ref --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."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
3
.github/workflows/publish-docs-component.yml
vendored
3
.github/workflows/publish-docs-component.yml
vendored
@ -9,6 +9,8 @@ jobs:
|
||||
docs_build:
|
||||
name: Docs-Build-And-Upload
|
||||
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
|
||||
@ -16,6 +18,7 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Generate docs
|
||||
run: |
|
||||
|
77
.github/workflows/publish-docs.yml
vendored
Normal file
77
.github/workflows/publish-docs.yml
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
name: Docs and Publish New
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
env:
|
||||
DOCS_DEPLOY_URL_BASE: "${{ secrets.DOCS_PREVIEW_SERVER_URL }}"
|
||||
#DOCS_DEPLOY_SERVER: "ci.espressif.cn:42348"
|
||||
DOCS_DEPLOY_SERVER: "ci.espressif.cn:42348"
|
||||
DOCS_DEPLOY_SERVER_USER: "${{ secrets.DOCS_SERVER_USER }}"
|
||||
DOCS_DEPLOY_PRIVATEKEY : "${{ secrets.DOCS_DEPLOY_KEY }}"
|
||||
DOCS_DEPLOY_KEY: "${{ secrets.DOCS_DEPLOY_KEY }}"
|
||||
DOCS_DEPLOY_PATH : "${{ secrets.DOCS_PATH }}"
|
||||
|
||||
jobs:
|
||||
docs_build:
|
||||
name: Docs-Build-And-Upload
|
||||
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
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
- name: Generate and delploying 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
|
||||
cd $GITHUB_WORKSPACE/components/esp_websocket_client/docs
|
||||
./generate_docs
|
||||
source $GITHUB_WORKSPACE/docs/utils.sh
|
||||
add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER
|
||||
export GIT_VER=$(git describe --always)
|
||||
ls -l $GITHUB_WORKSPACE/components/esp_websocket_client/docs
|
||||
export DOCS_BUILD_DIR=$GITHUB_WORKSPACE/components/esp_websocket_client/docs
|
||||
deploy-docs
|
||||
|
||||
#build_docs:
|
||||
# stage: build
|
||||
# image: $ESP_DOCS_ENV_IMAGE
|
||||
# tags:
|
||||
# - build_docs
|
||||
# artifacts:
|
||||
# when: always
|
||||
# paths:
|
||||
# - docs/_build/*/*/*.txt
|
||||
# - docs/_build/*/*/html/*
|
||||
# expire_in: 4 days
|
||||
# # No cleaning when the artifacts
|
||||
# after_script: []
|
||||
# script:
|
||||
# - cd docs
|
||||
# - pip install -r requirements.txt
|
||||
# - build-docs -l en -t esp32
|
||||
#
|
||||
#.deploy_docs_template:
|
||||
# stage: deploy
|
||||
# image: $ESP_DOCS_ENV_IMAGE
|
||||
# tags:
|
||||
# - deploy_docs
|
||||
# needs:
|
||||
# - build_docs
|
||||
# only:
|
||||
# changes:
|
||||
# - "docs/**/*"
|
||||
# script:
|
||||
# - source ${CI_PROJECT_DIR}/docs/utils.sh
|
||||
# - add_doc_server_ssh_keys ${{ secrets.DOCS_DEPLOY_PRIVATEKEY }} ${{ secrets.DOCS_DEPLOY_SERVER }} ${{ secrets.DOCS_DEPLOY_SERVER_USER }}
|
||||
# - export GIT_VER=$(git describe --always)
|
||||
# - pip install -r ${CI_PROJECT_DIR}/docs/requirements.txt
|
||||
# - deploy-docs
|
||||
#
|
338
.github/workflows/target-test.yml
vendored
338
.github/workflows/target-test.yml
vendored
@ -6,7 +6,7 @@ jobs:
|
||||
build_esp_modem:
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v4.1", "release-v4.2", "release-v4.3", "release-v4.4"]
|
||||
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:
|
||||
@ -35,12 +35,34 @@ jobs:
|
||||
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:
|
||||
@ -48,26 +70,23 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
path: esp-protocols
|
||||
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
|
||||
env:
|
||||
IDF_TARGET: ${{ matrix.idf_target }}
|
||||
- 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
|
||||
cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/examples/
|
||||
idf.py set-target ${{ matrix.idf_target }}
|
||||
cat sdkconfig.ci.eth_def >> sdkconfig.defaults
|
||||
idf.py build
|
||||
rm sdkconfig.defaults
|
||||
cat sdkconfig.ci.eth_custom_netif >> sdkconfig.defaults
|
||||
idf.py build
|
||||
rm sdkconfig.defaults
|
||||
cat sdkconfig.ci.eth_socket >> sdkconfig.defaults
|
||||
idf.py build
|
||||
cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/tests/test_apps/
|
||||
idf.py set-target ${{ matrix.idf_target }}
|
||||
idf.py build
|
||||
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:
|
||||
@ -75,62 +94,113 @@ jobs:
|
||||
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
|
||||
path: esp-protocols
|
||||
- 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
|
||||
cd $GITHUB_WORKSPACE/esp-protocols/components/asio/examples/${{ matrix.example }}
|
||||
test -f sdkconfig.ci && cat sdkconfig.ci >> sdkconfig.defaults || echo "No sdkconfig.ci"
|
||||
idf.py set-target ${{ matrix.idf_target }}
|
||||
idf.py build
|
||||
|
||||
build_websocket:
|
||||
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@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: components/esp_websocket_client/examples/
|
||||
run: |
|
||||
. ${IDF_PATH}/export.sh
|
||||
cat sdkconfig.ci >> sdkconfig.defaults
|
||||
idf.py build
|
||||
- name: Merge binaries
|
||||
working-directory: components/esp_websocket_client/examples/build
|
||||
- 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@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
|
||||
path: components/esp_websocket_client/examples/build/
|
||||
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
|
||||
|
||||
run-target:
|
||||
|
||||
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:
|
||||
@ -141,29 +211,173 @@ jobs:
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- ESP32-ETHERNET-KIT
|
||||
container:
|
||||
image: python:3.7-buster
|
||||
options: --privileged # Privileged mode has access to serial ports
|
||||
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@v2
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: examples_app_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}
|
||||
path: components/esp_websocket_client/examples/build/
|
||||
path: ${{ env.TEST_DIR }}/build/
|
||||
- name: Install Python packages
|
||||
env:
|
||||
PIP_EXTRA_INDEX_URL: "https://www.piwheels.org/simple"
|
||||
run: |
|
||||
pip install -r $GITHUB_WORKSPACE/components/esp_websocket_client/examples/requirements.txt
|
||||
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: components/esp_websocket_client/examples
|
||||
working-directory: ${{ env.TEST_DIR }}
|
||||
run: |
|
||||
cp sdkconfig.ci sdkconfig.defaults
|
||||
pytest --log-cli-level DEBUG --junit-xml=./test_app_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}.xml --target=${{ matrix.idf_target }}
|
||||
- uses: actions/upload-artifact@v2
|
||||
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: examples/*.xml
|
||||
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 }}
|
||||
|
94
.github/workflows/test_apps.yml
vendored
Normal file
94
.github/workflows/test_apps.yml
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
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
|
26
.mypy.ini
Normal file
26
.mypy.ini
Normal file
@ -0,0 +1,26 @@
|
||||
[mypy]
|
||||
|
||||
# Specifies the Python version used to parse and check the target program
|
||||
python_version = 3.9
|
||||
|
||||
# Disallows defining functions without type annotations or with incomplete type annotations
|
||||
# True => enforce type annotation in all function definitions
|
||||
disallow_untyped_defs = True
|
||||
|
||||
# Shows a warning when returning a value with type Any from a function declared with a non- Any return type
|
||||
warn_return_any = True
|
||||
|
||||
# Shows errors for missing return statements on some execution paths
|
||||
warn_no_return = True
|
||||
|
||||
# Suppress error messages about imports that cannot be resolved
|
||||
# True => ignore all import errors
|
||||
ignore_missing_imports = True
|
||||
|
||||
# Disallows defining functions with incomplete type annotations
|
||||
disallow_incomplete_defs = False
|
||||
|
||||
# Directs what to do with imports when the imported module is found as a .py file and not part of the files,
|
||||
# modules and packages provided on the command line.
|
||||
# SKIP -> mypy checks only single file, not included imports
|
||||
follow_imports = skip
|
52
.pre-commit-config.yaml
Normal file
52
.pre-commit-config.yaml
Normal file
@ -0,0 +1,52 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.3.0
|
||||
hooks:
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- id: fix-byte-order-marker
|
||||
- id: check-case-conflict
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- id: mixed-line-ending
|
||||
- id: debug-statements
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
rev: 5.0.4
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.981
|
||||
hooks:
|
||||
- id: mypy
|
||||
exclude: >
|
||||
(?x)^(
|
||||
.*.py
|
||||
)$
|
||||
- repo: https://github.com/myint/unify
|
||||
rev: v0.5
|
||||
hooks:
|
||||
- id: unify
|
||||
- repo: https://github.com/pre-commit/mirrors-yapf
|
||||
rev: "v0.32.0"
|
||||
hooks:
|
||||
- id: yapf
|
||||
- repo: https://github.com/pre-commit/mirrors-isort
|
||||
rev: v5.10.1
|
||||
hooks:
|
||||
- id: isort
|
||||
- repo: https://github.com/myint/eradicate/
|
||||
rev: v2.1.0
|
||||
hooks:
|
||||
- id: eradicate
|
||||
- repo: https://github.com/espressif/check-copyright/
|
||||
rev: v1.0.1
|
||||
hooks:
|
||||
- id: check-copyright
|
||||
args: ['--ignore', 'ci/check_copyright_ignore.txt', '--config', 'ci/check_copyright_config.yaml']
|
||||
- repo: https://github.com/igrr/astyle_py.git
|
||||
rev: c0013808882a15a0c0c2c1a9b5c903866c53a653
|
||||
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']
|
13
CONTRIBUTING.md
Normal file
13
CONTRIBUTING.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Information for Contributors
|
||||
|
||||
Contributions in the form of pull requests, issue reports, and feature requests are welcome!
|
||||
|
||||
## Submitting a PR
|
||||
|
||||
- [ ] 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`
|
||||
|
||||
- [ ] 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.
|
64
ci/check_copyright_config.yaml
Normal file
64
ci/check_copyright_config.yaml
Normal file
@ -0,0 +1,64 @@
|
||||
# don't modify this section!
|
||||
DEFAULT:
|
||||
perform_check: yes # should the check be performed?
|
||||
# Sections setting this to 'no' don't need to include any other options as they are ignored
|
||||
# When a file is using a section with the option set to 'no', no checks are performed.
|
||||
|
||||
# what licenses (or license expressions) are allowed for files in this section
|
||||
# when setting this option in a section, you need to list all the allowed licenses
|
||||
allowed_licenses:
|
||||
- Apache-2.0
|
||||
license_for_new_files: Apache-2.0 # license to be used when inserting a new copyright notice
|
||||
new_notice_c: | # notice for new C, CPP, H, HPP and LD files
|
||||
/*
|
||||
* SPDX-FileCopyrightText: {years} Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: {license}
|
||||
*/
|
||||
new_notice_python: | # notice for new python files
|
||||
# SPDX-FileCopyrightText: {years} Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: {license}
|
||||
|
||||
# comment lines matching:
|
||||
# SPDX-FileCopyrightText: year[-year] Espressif Systems
|
||||
# or
|
||||
# SPDX-FileContributor: year[-year] Espressif Systems
|
||||
# are replaced with this template prefixed with the correct comment notation (# or // or *) and SPDX- notation
|
||||
espressif_copyright: '{years} Espressif Systems (Shanghai) CO LTD'
|
||||
|
||||
# this section sets the default license for examples and unit tests of components
|
||||
examples_and_unit_tests:
|
||||
include:
|
||||
- 'components/**/examples/**'
|
||||
- 'components/**/test/**'
|
||||
- 'components/**/tests/**'
|
||||
- 'common_components/**'
|
||||
allowed_licenses:
|
||||
- Apache-2.0
|
||||
- Unlicense
|
||||
- CC0-1.0
|
||||
license_for_new_files: Unlicense OR CC0-1.0
|
||||
|
||||
asio_component:
|
||||
include:
|
||||
- 'components/asio/port/**'
|
||||
allowed_licenses:
|
||||
- Apache-2.0
|
||||
- BSL-1.0
|
||||
|
||||
slim_modem_examples:
|
||||
include:
|
||||
- 'examples/esp_netif/slip_custom_netif/**'
|
||||
allowed_licenses:
|
||||
- Apache-2.0
|
||||
- Unlicense
|
||||
- CC0-1.0
|
||||
|
||||
ignore:
|
||||
perform_check: no
|
||||
include:
|
||||
- 'components/**/docs/**'
|
||||
- 'components/esp_modem/port/linux/**'
|
||||
- 'components/asio/examples/**'
|
||||
- 'components/mdns/**/esp_system_protocols_linux/**'
|
||||
- 'common_components/protocol_examples_common/**'
|
0
ci/check_copyright_ignore.txt
Normal file
0
ci/check_copyright_ignore.txt
Normal file
7
ci/clean_build_artifacts.sh
Executable file
7
ci/clean_build_artifacts.sh
Executable file
@ -0,0 +1,7 @@
|
||||
# Remove everything, but
|
||||
# - elf/bin files in the build dir
|
||||
# - partition-table and bootloader binaries
|
||||
# - flasher args
|
||||
# - sdkconfigs (header and json)
|
||||
# (Ignoring the command failure as it refuses to delete nonempty dirs)
|
||||
find $1 ! -regex ".*/build[^/]*/[^/]+.\(bin\|elf\)" -a ! -regex ".*\(bootloader\|partition-table\).bin" -a ! -name "flasher_args.json" -a ! -regex ".*/build[^/]*/config/sdkconfig.\(h\|json\)" -delete || true
|
8
ci/requirements.txt
Normal file
8
ci/requirements.txt
Normal file
@ -0,0 +1,8 @@
|
||||
pytest-embedded-serial-esp
|
||||
pytest-embedded-idf
|
||||
junit_xml
|
||||
SimpleWebSocketServer
|
||||
dpkt
|
||||
pytest
|
||||
idf_build_apps
|
||||
netifaces
|
@ -1,10 +1,11 @@
|
||||
/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -396,7 +397,9 @@ static esp_netif_t *eth_start(void)
|
||||
#endif
|
||||
#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET
|
||||
gpio_install_isr_service(0);
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
spi_device_handle_t spi_handle = NULL;
|
||||
#endif
|
||||
spi_bus_config_t buscfg = {
|
||||
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
|
||||
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
|
||||
@ -414,9 +417,14 @@ static esp_netif_t *eth_start(void)
|
||||
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
|
||||
.queue_size = 20
|
||||
};
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
|
||||
/* dm9051 ethernet driver is based on spi driver */
|
||||
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
|
||||
#else
|
||||
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg);
|
||||
#endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
|
||||
dm9051_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
|
||||
s_mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
|
||||
s_phy = esp_eth_phy_new_dm9051(&phy_config);
|
||||
@ -429,9 +437,13 @@ static esp_netif_t *eth_start(void)
|
||||
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
|
||||
.queue_size = 20
|
||||
};
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
|
||||
/* w5500 ethernet driver is based on spi driver */
|
||||
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
|
||||
#else
|
||||
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg);
|
||||
#endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
w5500_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
|
||||
s_mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
|
||||
s_phy = esp_eth_phy_new_w5500(&phy_config);
|
||||
|
@ -1,13 +1,14 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
/* Common utilities for socket address input interface:
|
||||
The API get_addr_from_stdin() is mainly used by socket client examples which read IP address from stdin (if configured).
|
||||
This option is typically used in the CI, but could be enabled in the project configuration.
|
||||
In that case this component is used to receive a string that is evaluated and processed to output
|
||||
socket structures to open a connectio
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* Common functions for protocol examples, to configure stdin and stdout.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* Common functions for protocol examples, to configure stdin and stdout.
|
||||
*/
|
||||
|
||||
#include "protocol_examples_common.h"
|
||||
|
@ -1,5 +1,7 @@
|
||||
# ASIO port
|
||||
|
||||
[](https://components.espressif.com/components/espressif/asio)
|
||||
|
||||
Asio is a cross-platform C++ library, see https://think-async.com/Asio/. It provides a consistent asynchronous model using a modern C++ approach.
|
||||
|
||||
## Examples
|
||||
|
@ -1,6 +1,7 @@
|
||||
from esp_docs.conf_docs import * # noqa: F403,F401
|
||||
|
||||
extensions += ['sphinx_copybutton',
|
||||
extensions += [
|
||||
'sphinx_copybutton',
|
||||
# Needed as a trigger for running doxygen
|
||||
'esp_docs.esp_extensions.dummy_build_system',
|
||||
'esp_docs.esp_extensions.run_doxygen',
|
||||
|
@ -24,4 +24,3 @@ window.onload =(function() {
|
||||
|
||||
})();
|
||||
</script>" >> html/index.html
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
# 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.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
import ttfw_idf
|
||||
|
||||
|
||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC')
|
||||
def test_examples_asio_chat(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None
|
||||
msg = 'asio-chat: received hi'
|
||||
dut = env.get_dut('asio_chat', 'examples/protocols/asio/asio_chat')
|
||||
# start the test and expect the client to receive back it's original data
|
||||
dut.start_app()
|
||||
dut.expect(re.compile(r'{}'.format('Waiting for input')), timeout=30)
|
||||
dut.write(msg)
|
||||
dut.write('exit')
|
||||
dut.expect(re.compile(r'{}'.format(msg)), timeout=30)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_examples_asio_chat()
|
@ -53,14 +53,15 @@ void start_client(void)
|
||||
#ifdef CONFIG_EXAMPLE_CHAT_SERVER
|
||||
std::lock_guard<std::mutex> guard(server_ready);
|
||||
#endif
|
||||
std::thread t([&io_context]() { try {
|
||||
std::thread t([&io_context]() {
|
||||
try {
|
||||
io_context.run();
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGE(TAG, "Exception occured during client thread execution %s", e.what());
|
||||
}
|
||||
catch (...) {
|
||||
} catch (...) {
|
||||
ESP_LOGE(TAG, "Unknown exception");
|
||||
}});
|
||||
}
|
||||
});
|
||||
do {
|
||||
ESP_LOGI(TAG, "CLIENT: Waiting for input");
|
||||
get_string(line, sizeof(line));
|
||||
@ -99,10 +100,10 @@ extern "C" void app_main(void)
|
||||
io_context.run();
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGE(TAG, "Exception occured during server thread execution %s", e.what());
|
||||
}
|
||||
catch (...) {
|
||||
} catch (...) {
|
||||
ESP_LOGE(TAG, "Unknown exception");
|
||||
}});;
|
||||
}
|
||||
});;
|
||||
#endif
|
||||
#ifdef CONFIG_EXAMPLE_CHAT_CLIENT
|
||||
start_client();
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
class chat_message
|
||||
{
|
||||
class chat_message {
|
||||
public:
|
||||
static constexpr std::size_t header_length = 4;
|
||||
static constexpr std::size_t max_body_length = 512;
|
||||
@ -59,17 +58,17 @@ public:
|
||||
void body_length(std::size_t new_length)
|
||||
{
|
||||
body_length_ = new_length;
|
||||
if (body_length_ > max_body_length)
|
||||
if (body_length_ > max_body_length) {
|
||||
body_length_ = max_body_length;
|
||||
}
|
||||
}
|
||||
|
||||
bool decode_header()
|
||||
{
|
||||
char header[header_length + 1] = "";
|
||||
std::strncat(header, data_, header_length);
|
||||
body_length_ = std::atoi(header);
|
||||
if (body_length_ > max_body_length)
|
||||
{
|
||||
if (body_length_ > max_body_length) {
|
||||
body_length_ = 0;
|
||||
return false;
|
||||
}
|
||||
|
@ -17,8 +17,7 @@
|
||||
|
||||
typedef std::deque<chat_message> chat_message_queue;
|
||||
|
||||
class chat_client
|
||||
{
|
||||
class chat_client {
|
||||
public:
|
||||
chat_client(asio::io_context &io_context,
|
||||
const asio::ip::tcp::resolver::results_type &endpoints)
|
||||
@ -31,12 +30,10 @@ public:
|
||||
void write(const chat_message &msg)
|
||||
{
|
||||
asio::post(io_context_,
|
||||
[this, msg]()
|
||||
{
|
||||
[this, msg]() {
|
||||
bool write_in_progress = !write_msgs_.empty();
|
||||
write_msgs_.push_back(msg);
|
||||
if (!write_in_progress)
|
||||
{
|
||||
if (!write_in_progress) {
|
||||
do_write();
|
||||
}
|
||||
});
|
||||
@ -44,17 +41,17 @@ public:
|
||||
|
||||
void close()
|
||||
{
|
||||
asio::post(io_context_, [this]() { socket_.close(); });
|
||||
asio::post(io_context_, [this]() {
|
||||
socket_.close();
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
void do_connect(const asio::ip::tcp::resolver::results_type &endpoints)
|
||||
{
|
||||
asio::async_connect(socket_, endpoints,
|
||||
[this](std::error_code ec, asio::ip::tcp::endpoint)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
[this](std::error_code ec, asio::ip::tcp::endpoint) {
|
||||
if (!ec) {
|
||||
do_read_header();
|
||||
}
|
||||
});
|
||||
@ -64,14 +61,10 @@ void do_connect(const asio::ip::tcp::resolver::results_type& endpoints)
|
||||
{
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.data(), chat_message::header_length),
|
||||
[this](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec && read_msg_.decode_header())
|
||||
{
|
||||
[this](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec && read_msg_.decode_header()) {
|
||||
do_read_body();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
socket_.close();
|
||||
}
|
||||
});
|
||||
@ -81,14 +74,10 @@ void do_connect(const asio::ip::tcp::resolver::results_type& endpoints)
|
||||
{
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.body(), read_msg_.body_length()),
|
||||
[this](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
[this](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
do_read_header();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
socket_.close();
|
||||
}
|
||||
});
|
||||
@ -99,18 +88,13 @@ void do_connect(const asio::ip::tcp::resolver::results_type& endpoints)
|
||||
asio::async_write(socket_,
|
||||
asio::buffer(write_msgs_.front().data(),
|
||||
write_msgs_.front().length()),
|
||||
[this](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
[this](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
write_msgs_.pop_front();
|
||||
if (!write_msgs_.empty())
|
||||
{
|
||||
if (!write_msgs_.empty()) {
|
||||
do_write();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
socket_.close();
|
||||
}
|
||||
});
|
||||
|
@ -27,8 +27,7 @@ extern std::mutex server_ready;
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
class chat_participant
|
||||
{
|
||||
class chat_participant {
|
||||
public:
|
||||
virtual ~chat_participant() {}
|
||||
virtual void deliver(const chat_message &msg) = 0;
|
||||
@ -38,15 +37,15 @@ typedef std::shared_ptr<chat_participant> chat_participant_ptr;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class chat_room
|
||||
{
|
||||
class chat_room {
|
||||
public:
|
||||
void join(chat_participant_ptr participant)
|
||||
{
|
||||
participants_.insert(participant);
|
||||
for (auto msg: recent_msgs_)
|
||||
for (auto msg : recent_msgs_) {
|
||||
participant->deliver(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void leave(chat_participant_ptr participant)
|
||||
{
|
||||
@ -56,12 +55,14 @@ public:
|
||||
void deliver(const chat_message &msg)
|
||||
{
|
||||
recent_msgs_.push_back(msg);
|
||||
while (recent_msgs_.size() > max_recent_msgs)
|
||||
while (recent_msgs_.size() > max_recent_msgs) {
|
||||
recent_msgs_.pop_front();
|
||||
}
|
||||
|
||||
for (auto participant: participants_)
|
||||
for (auto participant : participants_) {
|
||||
participant->deliver(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<chat_participant_ptr> participants_;
|
||||
@ -74,8 +75,7 @@ private:
|
||||
|
||||
class chat_session
|
||||
: public chat_participant,
|
||||
public std::enable_shared_from_this<chat_session>
|
||||
{
|
||||
public std::enable_shared_from_this<chat_session> {
|
||||
public:
|
||||
chat_session(asio::ip::tcp::socket socket, chat_room &room)
|
||||
: socket_(std::move(socket)),
|
||||
@ -93,8 +93,7 @@ public:
|
||||
{
|
||||
bool write_in_progress = !write_msgs_.empty();
|
||||
write_msgs_.push_back(msg);
|
||||
if (!write_in_progress)
|
||||
{
|
||||
if (!write_in_progress) {
|
||||
do_write();
|
||||
}
|
||||
}
|
||||
@ -105,14 +104,10 @@ private:
|
||||
auto self(shared_from_this());
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.data(), chat_message::header_length),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec && read_msg_.decode_header())
|
||||
{
|
||||
[this, self](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec && read_msg_.decode_header()) {
|
||||
do_read_body();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
room_.leave(shared_from_this());
|
||||
}
|
||||
});
|
||||
@ -123,16 +118,12 @@ private:
|
||||
auto self(shared_from_this());
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.body(), read_msg_.body_length()),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
[this, self](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
ESP_LOGD("asio-chat:", "%s", read_msg_.body());
|
||||
room_.deliver(read_msg_);
|
||||
do_read_header();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
room_.leave(shared_from_this());
|
||||
}
|
||||
});
|
||||
@ -144,18 +135,13 @@ private:
|
||||
asio::async_write(socket_,
|
||||
asio::buffer(write_msgs_.front().data(),
|
||||
write_msgs_.front().length()),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
[this, self](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
write_msgs_.pop_front();
|
||||
if (!write_msgs_.empty())
|
||||
{
|
||||
if (!write_msgs_.empty()) {
|
||||
do_write();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
room_.leave(shared_from_this());
|
||||
}
|
||||
});
|
||||
@ -169,8 +155,7 @@ private:
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class chat_server
|
||||
{
|
||||
class chat_server {
|
||||
public:
|
||||
chat_server(asio::io_context &io_context,
|
||||
const asio::ip::tcp::endpoint &endpoint)
|
||||
@ -184,10 +169,8 @@ private:
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(server_ready);
|
||||
acceptor_.async_accept(
|
||||
[this](std::error_code ec, asio::ip::tcp::socket socket)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
[this](std::error_code ec, asio::ip::tcp::socket socket) {
|
||||
if (!ec) {
|
||||
std::make_shared<chat_session>(std::move(socket), room_)->start();
|
||||
}
|
||||
|
||||
|
16
components/asio/examples/asio_chat/pytest_asio_chat_test.py
Normal file
16
components/asio/examples/asio_chat/pytest_asio_chat_test.py
Normal file
@ -0,0 +1,16 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
|
||||
|
||||
def test_examples_asio_chat(dut):
|
||||
msg = 'asio-chat: received hi'
|
||||
# start the test and expect the client to receive back it's original data
|
||||
dut.expect(re.compile(b'Waiting for input'), timeout=30)
|
||||
dut.write(msg)
|
||||
dut.write('exit')
|
||||
msg = bytes(msg, encoding='utf8')
|
||||
dut.expect(re.compile(msg), timeout=30)
|
@ -1,2 +1,8 @@
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||||
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
# Leave some room for larger apps without needing to reduce other features
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
|
||||
|
@ -70,4 +70,3 @@ ssh -N -v -D 0.0.0.0:1080 localhost
|
||||
# Async operations composition and automatic lifetime control
|
||||
|
||||
For documentation about the structure of this example look into [async\_request README](../async_request/README.md).
|
||||
|
||||
|
@ -20,11 +20,9 @@ namespace socks4 {
|
||||
|
||||
const unsigned char version = 0x04;
|
||||
|
||||
class request
|
||||
{
|
||||
class request {
|
||||
public:
|
||||
enum command_type
|
||||
{
|
||||
enum command_type {
|
||||
connect = 0x01,
|
||||
bind = 0x02
|
||||
};
|
||||
@ -37,8 +35,7 @@ public:
|
||||
null_byte_(0)
|
||||
{
|
||||
// Only IPv4 is supported by the SOCKS 4 protocol.
|
||||
if (endpoint.protocol() != asio::ip::tcp::v4())
|
||||
{
|
||||
if (endpoint.protocol() != asio::ip::tcp::v4()) {
|
||||
throw asio::system_error(
|
||||
asio::error::address_family_not_supported);
|
||||
}
|
||||
@ -54,8 +51,7 @@ public:
|
||||
|
||||
std::array<asio::const_buffer, 7> buffers() const
|
||||
{
|
||||
return
|
||||
{
|
||||
return {
|
||||
{
|
||||
asio::buffer(&version_, 1),
|
||||
asio::buffer(&command_, 1),
|
||||
@ -78,11 +74,9 @@ private:
|
||||
unsigned char null_byte_;
|
||||
};
|
||||
|
||||
class reply
|
||||
{
|
||||
class reply {
|
||||
public:
|
||||
enum status_type
|
||||
{
|
||||
enum status_type {
|
||||
request_granted = 0x5a,
|
||||
request_failed = 0x5b,
|
||||
request_failed_no_identd = 0x5c,
|
||||
@ -97,8 +91,7 @@ public:
|
||||
|
||||
std::array<asio::mutable_buffer, 5> buffers()
|
||||
{
|
||||
return
|
||||
{
|
||||
return {
|
||||
{
|
||||
asio::buffer(&null_byte_, 1),
|
||||
asio::buffer(&status_, 1),
|
||||
|
@ -1,16 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import ttfw_idf
|
||||
|
||||
|
||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
|
||||
def test_examples_asio_ssl(env, extra_data):
|
||||
|
||||
dut = env.get_dut('asio_ssl_client_server', 'examples/protocols/asio/ssl_client_server')
|
||||
dut.start_app()
|
||||
|
||||
dut.expect('Reply: GET / HTTP/1.1')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_examples_asio_ssl()
|
@ -0,0 +1,7 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
def test_examples_asio_ssl(dut):
|
||||
dut.expect('Reply: GET / HTTP/1.1')
|
@ -1,47 +0,0 @@
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
|
||||
import ttfw_idf
|
||||
|
||||
|
||||
@ttfw_idf.idf_example_test(env_tag='Example_WIFI_Protocols')
|
||||
def test_examples_protocol_asio_tcp_server(env, extra_data):
|
||||
"""
|
||||
steps: |
|
||||
1. join AP
|
||||
2. Start server
|
||||
3. Test connects to server and sends a test message
|
||||
4. Test evaluates received test message from server
|
||||
5. Test evaluates received test message on server stdout
|
||||
"""
|
||||
test_msg = b'echo message from client to server'
|
||||
dut1 = env.get_dut('tcp_echo_server', 'examples/protocols/asio/tcp_echo_server', dut_class=ttfw_idf.ESP32DUT)
|
||||
# check and log bin size
|
||||
binary_file = os.path.join(dut1.app.binary_path, 'asio_tcp_echo_server.bin')
|
||||
bin_size = os.path.getsize(binary_file)
|
||||
ttfw_idf.log_performance('asio_tcp_echo_server_bin_size', '{}KB'.format(bin_size // 1024))
|
||||
# 1. start test
|
||||
dut1.start_app()
|
||||
# 2. get the server IP address
|
||||
data = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)
|
||||
# 3. create tcp client and connect to server
|
||||
dut1.expect('ASIO engine is up and running', timeout=1)
|
||||
cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
cli.settimeout(30)
|
||||
cli.connect((data[0], 2222))
|
||||
cli.send(test_msg)
|
||||
data = cli.recv(1024)
|
||||
# 4. check the message received back from the server
|
||||
if (data == test_msg):
|
||||
print('PASS: Received correct message')
|
||||
pass
|
||||
else:
|
||||
print('Failure!')
|
||||
raise ValueError('Wrong data received from asi tcp server: {} (expected:{})'.format(data, test_msg))
|
||||
# 5. check the client message appears also on server terminal
|
||||
dut1.expect(test_msg.decode())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_examples_protocol_asio_tcp_server()
|
@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "asio.hpp"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -8,8 +13,7 @@
|
||||
using asio::ip::tcp;
|
||||
|
||||
class session
|
||||
: public std::enable_shared_from_this<session>
|
||||
{
|
||||
: public std::enable_shared_from_this<session> {
|
||||
public:
|
||||
session(tcp::socket socket)
|
||||
: socket_(std::move(socket))
|
||||
@ -26,10 +30,8 @@ private:
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
socket_.async_read_some(asio::buffer(data_, max_length),
|
||||
[this, self](std::error_code ec, std::size_t length)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
[this, self](std::error_code ec, std::size_t length) {
|
||||
if (!ec) {
|
||||
data_[length] = 0;
|
||||
std::cout << data_ << std::endl;
|
||||
do_write(length);
|
||||
@ -41,10 +43,8 @@ private:
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
asio::async_write(socket_, asio::buffer(data_, length),
|
||||
[this, self](std::error_code ec, std::size_t length)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
[this, self](std::error_code ec, std::size_t length) {
|
||||
if (!ec) {
|
||||
do_read();
|
||||
}
|
||||
});
|
||||
@ -55,8 +55,7 @@ private:
|
||||
char data_[max_length];
|
||||
};
|
||||
|
||||
class server
|
||||
{
|
||||
class server {
|
||||
public:
|
||||
server(asio::io_context &io_context, short port)
|
||||
: acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
|
||||
@ -68,10 +67,8 @@ private:
|
||||
void do_accept()
|
||||
{
|
||||
acceptor_.async_accept(
|
||||
[this](std::error_code ec, tcp::socket socket)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
[this](std::error_code ec, tcp::socket socket) {
|
||||
if (!ec) {
|
||||
std::make_shared<session>(std::move(socket))->start();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,39 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import re
|
||||
import socket
|
||||
|
||||
|
||||
def test_examples_protocol_asio_tcp_server(dut):
|
||||
"""
|
||||
steps: |
|
||||
1. join AP
|
||||
2. Start server
|
||||
3. Test connects to server and sends a test message
|
||||
4. Test evaluates received test message from server
|
||||
5. Test evaluates received test message on server stdout
|
||||
"""
|
||||
test_msg = b'echo message from client to server'
|
||||
# 2. get the server IP address
|
||||
data = dut.expect(
|
||||
re.compile(
|
||||
b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), # noqa: W605
|
||||
timeout=30).group(1).decode()
|
||||
# 3. create tcp client and connect to server
|
||||
dut.expect('ASIO engine is up and running', timeout=1)
|
||||
cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
cli.settimeout(30)
|
||||
cli.connect((data, 2222))
|
||||
cli.send(test_msg)
|
||||
data = cli.recv(1024)
|
||||
# 4. check the message received back from the server
|
||||
if (data == test_msg):
|
||||
print('PASS: Received correct message')
|
||||
pass
|
||||
else:
|
||||
print('Failure!')
|
||||
raise ValueError(
|
||||
'Wrong data received from asi tcp server: {} (expected:{})'.format(
|
||||
data, test_msg))
|
||||
# 5. check the client message appears also on server terminal
|
||||
dut.expect(test_msg.decode())
|
2
components/asio/examples/tcp_echo_server/sdkconfig.ci
Normal file
2
components/asio/examples/tcp_echo_server/sdkconfig.ci
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
@ -1,47 +0,0 @@
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
|
||||
import ttfw_idf
|
||||
|
||||
|
||||
@ttfw_idf.idf_example_test(env_tag='Example_WIFI_Protocols')
|
||||
def test_examples_protocol_asio_udp_server(env, extra_data):
|
||||
"""
|
||||
steps: |
|
||||
1. join AP
|
||||
2. Start server
|
||||
3. Test connects to server and sends a test message
|
||||
4. Test evaluates received test message from server
|
||||
5. Test evaluates received test message on server stdout
|
||||
"""
|
||||
test_msg = b'echo message from client to server'
|
||||
dut1 = env.get_dut('udp_echo_server', 'examples/protocols/asio/udp_echo_server', dut_class=ttfw_idf.ESP32DUT)
|
||||
# check and log bin size
|
||||
binary_file = os.path.join(dut1.app.binary_path, 'asio_udp_echo_server.bin')
|
||||
bin_size = os.path.getsize(binary_file)
|
||||
ttfw_idf.log_performance('asio_udp_echo_server_bin_size', '{}KB'.format(bin_size // 1024))
|
||||
# 1. start test
|
||||
dut1.start_app()
|
||||
# 2. get the server IP address
|
||||
data = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)
|
||||
# 3. create tcp client and connect to server
|
||||
dut1.expect('ASIO engine is up and running', timeout=1)
|
||||
cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
cli.settimeout(30)
|
||||
cli.connect((data[0], 2222))
|
||||
cli.send(test_msg)
|
||||
data = cli.recv(1024)
|
||||
# 4. check the message received back from the server
|
||||
if (data == test_msg):
|
||||
print('PASS: Received correct message')
|
||||
pass
|
||||
else:
|
||||
print('Failure!')
|
||||
raise ValueError('Wrong data received from asio udp server: {} (expected:{})'.format(data, test_msg))
|
||||
# 5. check the client message appears also on server terminal
|
||||
dut1.expect(test_msg.decode())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_examples_protocol_asio_udp_server()
|
@ -20,8 +20,7 @@
|
||||
|
||||
using asio::ip::udp;
|
||||
|
||||
class server
|
||||
{
|
||||
class server {
|
||||
public:
|
||||
server(asio::io_context &io_context, short port)
|
||||
: socket_(io_context, udp::endpoint(udp::v4(), port))
|
||||
@ -33,16 +32,12 @@ public:
|
||||
{
|
||||
socket_.async_receive_from(
|
||||
asio::buffer(data_, max_length), sender_endpoint_,
|
||||
[this](std::error_code ec, std::size_t bytes_recvd)
|
||||
{
|
||||
if (!ec && bytes_recvd > 0)
|
||||
{
|
||||
[this](std::error_code ec, std::size_t bytes_recvd) {
|
||||
if (!ec && bytes_recvd > 0) {
|
||||
data_[bytes_recvd] = 0;
|
||||
std::cout << data_ << std::endl;
|
||||
do_send(bytes_recvd);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
do_receive();
|
||||
}
|
||||
});
|
||||
@ -52,8 +47,7 @@ public:
|
||||
{
|
||||
socket_.async_send_to(
|
||||
asio::buffer(data_, length), sender_endpoint_,
|
||||
[this](std::error_code /*ec*/, std::size_t bytes /*bytes_sent*/)
|
||||
{
|
||||
[this](std::error_code /*ec*/, std::size_t bytes /*bytes_sent*/) {
|
||||
do_receive();
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import re
|
||||
import socket
|
||||
|
||||
|
||||
def test_examples_protocol_asio_udp_server(dut):
|
||||
"""
|
||||
steps: |
|
||||
1. join AP
|
||||
2. Start server
|
||||
3. Test connects to server and sends a test message
|
||||
4. Test evaluates received test message from server
|
||||
5. Test evaluates received test message on server stdout
|
||||
"""
|
||||
test_msg = b'echo message from client to server'
|
||||
data = dut.expect(
|
||||
re.compile(
|
||||
b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), # noqa: W605
|
||||
timeout=30).group(1).decode()
|
||||
dut.expect('ASIO engine is up and running', timeout=1)
|
||||
cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
cli.settimeout(30)
|
||||
cli.connect((data, 2222))
|
||||
cli.send(test_msg)
|
||||
data = cli.recv(1024)
|
||||
# 4. check the message received back from the server
|
||||
if (data == test_msg):
|
||||
print('PASS: Received correct message')
|
||||
pass
|
||||
else:
|
||||
print('Failure!')
|
||||
raise ValueError(
|
||||
'Wrong data received from asio udp server: {} (expected:{})'.
|
||||
format(data, test_msg))
|
||||
# 5. check the client message appears also on server terminal
|
||||
dut.expect(test_msg.decode())
|
2
components/asio/examples/udp_echo_server/sdkconfig.ci
Normal file
2
components/asio/examples/udp_echo_server/sdkconfig.ci
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
@ -1,4 +1,4 @@
|
||||
version: "1.0.2"
|
||||
version: "1.14.1~3"
|
||||
description: ASIO
|
||||
dependencies:
|
||||
idf:
|
||||
|
@ -24,7 +24,8 @@ void throw_exception(const Exception& e)
|
||||
ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what());
|
||||
abort();
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_COMPILER_CXX_EXCEPTIONS==1 && defined (ASIO_NO_EXCEPTIONS)
|
||||
|
||||
#endif // _ESP_EXCEPTION_H_
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
@ -35,7 +35,9 @@ namespace mbedtls {
|
||||
class engine;
|
||||
class bio;
|
||||
class shared_ctx;
|
||||
} } } // namespace asio::ssl::mbedtls
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::mbedtls
|
||||
|
||||
//
|
||||
// Supply OpenSSL types as aliases to mbedtls classes
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
@ -110,4 +110,6 @@ private:
|
||||
size_t flags_ {0};
|
||||
};
|
||||
|
||||
} } } // namespace asio::ssl::mbedtls
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::mbedtls
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
@ -29,8 +29,7 @@ template <typename T, typename... Args>
|
||||
inline T *create(const char *location, Args &&... args)
|
||||
{
|
||||
T *t = new (std::nothrow) T(std::forward<Args>(args)...);
|
||||
if (t == nullptr)
|
||||
{
|
||||
if (t == nullptr) {
|
||||
throw_alloc_failure(location);
|
||||
}
|
||||
return t;
|
||||
@ -83,8 +82,7 @@ public:
|
||||
static SSL_CTX *create(const char *location, context_base::method m)
|
||||
{
|
||||
auto wrapped = asio::ssl::mbedtls::create<shared_ctx>(location, m);
|
||||
if (wrapped->ctx_ == nullptr)
|
||||
{
|
||||
if (wrapped->ctx_ == nullptr) {
|
||||
throw_alloc_failure(location);
|
||||
}
|
||||
return wrapped;
|
||||
@ -102,4 +100,6 @@ private:
|
||||
std::shared_ptr<mbedtls::context> ctx_;
|
||||
};
|
||||
|
||||
} } } // namespace asio::ssl::mbedtls
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::mbedtls
|
||||
|
@ -163,18 +163,20 @@ private:
|
||||
{
|
||||
int mode = MBEDTLS_SSL_VERIFY_UNSET;
|
||||
if (is_client_not_server) {
|
||||
if (verify_mode_ & SSL_VERIFY_PEER)
|
||||
if (verify_mode_ & SSL_VERIFY_PEER) {
|
||||
mode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
else if (verify_mode_ == SSL_VERIFY_NONE)
|
||||
} else if (verify_mode_ == SSL_VERIFY_NONE) {
|
||||
mode = MBEDTLS_SSL_VERIFY_NONE;
|
||||
}
|
||||
} else {
|
||||
if (verify_mode_ & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
|
||||
if (verify_mode_ & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
|
||||
mode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
else if (verify_mode_ & SSL_VERIFY_PEER)
|
||||
} else if (verify_mode_ & SSL_VERIFY_PEER) {
|
||||
mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
|
||||
else if (verify_mode_ == SSL_VERIFY_NONE)
|
||||
} else if (verify_mode_ == SSL_VERIFY_NONE) {
|
||||
mode = MBEDTLS_SSL_VERIFY_NONE;
|
||||
}
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
@ -290,4 +292,6 @@ private:
|
||||
asio::ssl::verify_mode verify_mode_;
|
||||
};
|
||||
|
||||
} } } // namespace asio::ssl::mbedtls
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::mbedtls
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
@ -14,8 +14,7 @@ namespace asio {
|
||||
namespace error {
|
||||
namespace detail {
|
||||
|
||||
class mbedtls_category : public asio::error_category
|
||||
{
|
||||
class mbedtls_category : public asio::error_category {
|
||||
public:
|
||||
const char *name() const ASIO_ERROR_CATEGORY_NOEXCEPT
|
||||
{
|
||||
@ -52,4 +51,6 @@ const asio::error_category& get_stream_category()
|
||||
return asio::error::get_mbedtls_category();
|
||||
}
|
||||
|
||||
} } } // namespace asio::ssl::error
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::error
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -4,7 +4,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
// SPDX-FileContributor: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileContributor: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
|
@ -3,7 +3,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
// SPDX-FileContributor: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileContributor: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
@ -62,8 +62,7 @@ engine::want engine::shutdown(asio::error_code& ec)
|
||||
engine::want engine::write(const asio::const_buffer &data,
|
||||
asio::error_code &ec, std::size_t &bytes_transferred)
|
||||
{
|
||||
if (data.size() == 0)
|
||||
{
|
||||
if (data.size() == 0) {
|
||||
ec = asio::error_code();
|
||||
return engine::want_nothing;
|
||||
}
|
||||
@ -76,8 +75,7 @@ engine::want engine::write(const asio::const_buffer& data,
|
||||
engine::want engine::read(const asio::mutable_buffer &data,
|
||||
asio::error_code &ec, std::size_t &bytes_transferred)
|
||||
{
|
||||
if (data.size() == 0)
|
||||
{
|
||||
if (data.size() == 0) {
|
||||
ec = asio::error_code();
|
||||
return engine::want_nothing;
|
||||
}
|
||||
@ -108,19 +106,18 @@ const asio::error_code& engine::map_error_code(
|
||||
asio::error_code &ec) const
|
||||
{
|
||||
// We only want to map the error::eof code.
|
||||
if (ec != asio::error::eof)
|
||||
if (ec != asio::error::eof) {
|
||||
return ec;
|
||||
}
|
||||
|
||||
// If there's data yet to be read, it's an error.
|
||||
if (ssl_->ext_bio()->wpending())
|
||||
{
|
||||
if (ssl_->ext_bio()->wpending()) {
|
||||
ec = asio::ssl::error::stream_truncated;
|
||||
return ec;
|
||||
}
|
||||
|
||||
// Otherwise, the peer should have negotiated a proper shutdown.
|
||||
if (ssl_->shutdown() != 0)
|
||||
{
|
||||
if (ssl_->shutdown() != 0) {
|
||||
ec = asio::ssl::error::stream_truncated;
|
||||
}
|
||||
|
||||
@ -138,38 +135,30 @@ engine::want engine::perform(int (engine::* op)(void*, std::size_t),
|
||||
|
||||
std::size_t pending_output_after = ssl_->ext_bio()->ctrl_pending();
|
||||
|
||||
if (mbedtls::error_codes::is_error(result))
|
||||
{
|
||||
if (mbedtls::error_codes::is_error(result)) {
|
||||
ec = asio::error_code(result, asio::error::get_mbedtls_category());
|
||||
return pending_output_after > pending_output_before ? want_output : want_nothing;
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
if (result == 0) {
|
||||
return pending_output_after > pending_output_before
|
||||
? want_output : want_nothing;
|
||||
}
|
||||
|
||||
if (result > 0 && bytes_transferred)
|
||||
if (result > 0 && bytes_transferred) {
|
||||
*bytes_transferred = static_cast<std::size_t>(result);
|
||||
}
|
||||
|
||||
if (mbedtls::error_codes::want_write(result))
|
||||
{
|
||||
if (mbedtls::error_codes::want_write(result)) {
|
||||
ec = asio::error_code();
|
||||
return want_output_and_retry;
|
||||
}
|
||||
else if (pending_output_after > pending_output_before)
|
||||
{
|
||||
} else if (pending_output_after > pending_output_before) {
|
||||
ec = asio::error_code();
|
||||
return result > 0 ? want_output : want_output_and_retry;
|
||||
}
|
||||
else if (mbedtls::error_codes::want_read(result))
|
||||
{
|
||||
} else if (mbedtls::error_codes::want_read(result)) {
|
||||
ec = asio::error_code();
|
||||
return want_input_and_retry;
|
||||
}
|
||||
else if (ssl_->get_state() == mbedtls::CLOSED)
|
||||
{
|
||||
} else if (ssl_->get_state() == mbedtls::CLOSED) {
|
||||
ec = asio::error::eof;
|
||||
return want_nothing;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
@ -17,4 +17,6 @@ asio::detail::shared_ptr<openssl_init_base::do_init> openssl_init_base::instance
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} } } // namespace asio::ssl::detail
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::detail
|
||||
|
3
components/esp_modem/.gitignore
vendored
3
components/esp_modem/.gitignore
vendored
@ -91,3 +91,6 @@ dependencies.lock
|
||||
|
||||
# ignore generated docs
|
||||
docs/html
|
||||
|
||||
# esp-idf managed components
|
||||
**/managed_components/**
|
||||
|
@ -14,6 +14,7 @@ else()
|
||||
set(dependencies driver esp_event esp_netif)
|
||||
endif()
|
||||
|
||||
|
||||
set(srcs ${platform_srcs}
|
||||
"src/esp_modem_dte.cpp"
|
||||
"src/esp_modem_dce.cpp"
|
||||
@ -34,15 +35,27 @@ idf_component_register(SRCS "${srcs}"
|
||||
PRIV_INCLUDE_DIRS private_include
|
||||
REQUIRES ${dependencies})
|
||||
|
||||
|
||||
set_target_properties(${COMPONENT_LIB} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
)
|
||||
|
||||
|
||||
if(${target} STREQUAL "linux")
|
||||
# This is needed for ESP_LOGx() macros, as integer formats differ on ESP32(..) and x64
|
||||
set_target_properties(${COMPONENT_LIB} PROPERTIES COMPILE_FLAGS -Wno-format)
|
||||
endif()
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
if(CONFIG_GCOV_ENABLED)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
|
||||
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
CMAKE_CXX_FLAGS_COVERAGE
|
||||
CMAKE_C_FLAGS_COVERAGE
|
||||
CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
|
||||
endif()
|
||||
|
28
components/esp_modem/Kconfig
Normal file
28
components/esp_modem/Kconfig
Normal file
@ -0,0 +1,28 @@
|
||||
menu "esp-modem"
|
||||
|
||||
config ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD
|
||||
bool "Defragment CMUX messages internally"
|
||||
default y
|
||||
help
|
||||
If enabled (default), the esp-modem automatically defragments CMUX messages
|
||||
to only pass the completed CMUX message to higher layers.
|
||||
This is useful for messages in command mode (if they're received fragmented).
|
||||
It's not a problem for messages in data mode as the upper layer (PPP protocol)
|
||||
defines message boundaries.
|
||||
Keep the default to true for most cases (as most devices use simply 1 byte CMUX
|
||||
length, as the internal Rx buffer of size >= 256 bytes won't overflow)
|
||||
Set to false if your devices uses 2 byte CMUX payload (e.g. A7672S).
|
||||
The operation would work without an issue in data mode, but some replies
|
||||
in command mode might come fragmented in rare cases so might need to retry
|
||||
AT commands.
|
||||
|
||||
config ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP
|
||||
int "Delay in ms to wait before creating another virtual terminal"
|
||||
default 0
|
||||
help
|
||||
Some devices might need a pause before sending SABM command that creates
|
||||
virtual terminal. This delay applies only to establishing a CMUX mode.
|
||||
The typical reason for failing SABM request without a delay is that
|
||||
some devices (SIM800) send MSC requests just after opening a new DLCI.
|
||||
|
||||
endmenu
|
@ -1,5 +1,7 @@
|
||||
# ESP MODEM
|
||||
|
||||
[](https://components.espressif.com/components/espressif/esp_modem)
|
||||
|
||||
The `esp-modem` component is a managed component for `esp-idf` that is used for communication with GSM/LTE modems
|
||||
that support AT commands and PPP protocol as a network interface.
|
||||
|
||||
|
@ -2522,4 +2522,3 @@ DOT_CLEANUP = YES
|
||||
#DOT_GRAPH_MAX_NODES = 100
|
||||
#MAX_DOT_GRAPH_DEPTH = 0
|
||||
#DOT_TRANSPARENT = YES
|
||||
|
||||
|
@ -69,10 +69,24 @@ after creating multiple virtual terminals, designating some of them solely to da
|
||||
|
||||
### DTE's
|
||||
|
||||
Currently we support only UART, but modern modules support other communication interfaces, such as USB, SPI.
|
||||
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`
|
||||
|
@ -46,4 +46,3 @@ a custom DTE object and supply it into :ref:`the DCE factory<dce_factory>`. The
|
||||
- Create the DTE which uses the custom Terminal
|
||||
|
||||
Please refer to the implementation of the existing UART DTE.
|
||||
|
||||
|
@ -2,11 +2,6 @@
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
#
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# General information about the project.
|
||||
project = u'esp-modem'
|
||||
@ -18,11 +13,12 @@ language = 'en'
|
||||
|
||||
extensions = ['breathe', 'recommonmark']
|
||||
|
||||
|
||||
breathe_projects = {'esp_modem': 'xml'}
|
||||
|
||||
breathe_default_project = "esp_modem"
|
||||
breathe_default_project = 'esp_modem'
|
||||
|
||||
source_suffix = ['.rst', '.md']
|
||||
|
||||
source_parsers = {'.md': 'recommonmark.parser.CommonMarkParser', }
|
||||
source_parsers = {
|
||||
'.md': 'recommonmark.parser.CommonMarkParser',
|
||||
}
|
||||
|
@ -115,8 +115,3 @@ Modem types
|
||||
|
||||
.. doxygengroup:: ESP_MODEM_TYPES
|
||||
:members:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -7,3 +7,4 @@ endif()
|
||||
idf_component_register(SRCS "ap_to_pppos.c"
|
||||
${NETWORK_DCE}
|
||||
INCLUDE_DIRS ".")
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
|
@ -1,22 +1,24 @@
|
||||
/* softAP to PPPoS Example
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* softAP to PPPoS Example
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_idf_version.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "lwip/lwip_napt.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "network_dce.h"
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
#include "esp_mac.h"
|
||||
#include "dhcpserver/dhcpserver.h"
|
||||
#endif
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* softAP to PPPoS Example (network_dce)
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* softAP to PPPoS Example (network_dce)
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* softAP to PPPoS Example (network_dce)
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* softAP to PPPoS Example (network_dce)
|
||||
*/
|
||||
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
@ -92,8 +93,9 @@ public:
|
||||
bool check_signal()
|
||||
{
|
||||
int rssi, ber;
|
||||
if (dce_commands::get_signal_quality(dte.get(), rssi, ber) != command_result::OK)
|
||||
if (dce_commands::get_signal_quality(dte.get(), rssi, ber) != command_result::OK) {
|
||||
return false;
|
||||
}
|
||||
return rssi != 99 && rssi > 5;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* softAP to PPPoS Example (network_dce)
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* softAP to PPPoS Example (network_dce)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include <unistd.h>
|
||||
@ -61,7 +66,7 @@ int main()
|
||||
|
||||
bool pin_ok = true;
|
||||
if (dce->read_pin(pin_ok) == command_result::OK && !pin_ok) {
|
||||
throw_if_false(dce->set_pin(CONFIG_EXAMPLE_SIM_PIN) == command_result::OK, "Cannot set PIN!");
|
||||
ESP_MODEM_THROW_IF_FALSE(dce->set_pin(CONFIG_EXAMPLE_SIM_PIN) == command_result::OK, "Cannot set PIN!");
|
||||
usleep(1000000);
|
||||
}
|
||||
std::string str;
|
||||
|
@ -2,15 +2,5 @@
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS "../..")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/version.cmake)
|
||||
|
||||
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "4.4")
|
||||
if(("${IDF_TARGET}" STREQUAL "esp32s2") OR ("${IDF_TARGET}" STREQUAL "esp32s3"))
|
||||
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/peripherals/usb/host/cdc/common")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(modem-console)
|
||||
|
@ -8,4 +8,3 @@ PROJECT_NAME := modem-console
|
||||
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
||||
|
@ -20,7 +20,11 @@ For USB enabled targets (ESP32-S2 and ESP32-S3), it is possible to connect to th
|
||||
1. In menuconfig, navigate to `Example Configuration->Type of serial connection to the modem` and choose `USB`.
|
||||
2. Connect the modem USB signals to pin 19 (DATA-) and 20 (DATA+) on your ESP chip.
|
||||
|
||||
USB example uses Quactel BG96 modem device.
|
||||
USB example uses Quactel BG96 modem device. BG96 needs a positive pulse on its PWK pin to boot-up.
|
||||
|
||||
This example supports USB modem hot-plugging and reconnection. There is one limitation coming from esp_console component:
|
||||
When esp_console REPL is being destroyed (after USB mode disconnection or after `exit` command), it will block on UART read.
|
||||
You must send a character to it (via idf.py monitor), so it unblocks and properly exits.
|
||||
|
||||
### Supported IDF versions
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
include($ENV{IDF_PATH}/tools/cmake/version.cmake)
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
|
||||
# USB is supported on S2 and S3 targets and IDF version >= 4.4
|
||||
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "4.4")
|
||||
if(("${target}" STREQUAL "esp32s2") OR ("${target}" STREQUAL "esp32s3"))
|
||||
|
||||
idf_component_register(SRCS "esp_modem_usb.cpp" "esp_modem_usb_api_target.cpp"
|
||||
REQUIRES cdc_acm_host esp_modem
|
||||
REQUIRED_IDF_TARGETS esp32s2 esp32s3
|
||||
PRIV_INCLUDE_DIRS "private_include"
|
||||
INCLUDE_DIRS "include")
|
||||
|
||||
set_target_properties(${COMPONENT_LIB} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
)
|
||||
|
||||
endif()
|
||||
endif()
|
@ -1,191 +0,0 @@
|
||||
// Copyright 2021 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_modem_config.h"
|
||||
#include "esp_modem_usb_config.h"
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "usb/usb_host.h"
|
||||
#include "usb/cdc_acm_host.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "usb_terminal.hpp"
|
||||
|
||||
static const char *TAG = "usb_terminal";
|
||||
|
||||
/**
|
||||
* @brief USB Host task
|
||||
*
|
||||
* This task is created only if install_usb_host is set to true in DTE configuration.
|
||||
* In case the user doesn't want in install USB Host driver here, he must install it before creating UsbTerminal object.
|
||||
*
|
||||
* @param arg Unused
|
||||
*/
|
||||
void usb_host_task(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
// Start handling system events
|
||||
uint32_t event_flags;
|
||||
usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
|
||||
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
|
||||
ESP_LOGD(TAG, "No more clients: clean up\n");
|
||||
usb_host_device_free_all();
|
||||
}
|
||||
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
|
||||
ESP_LOGD(TAG, "All free: uninstall USB lib\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up USB Host
|
||||
vTaskDelay(10); // Short delay to allow clients clean-up
|
||||
usb_host_lib_handle_events(0, NULL); // Make sure there are now pending events
|
||||
usb_host_uninstall();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
namespace esp_modem {
|
||||
class UsbTerminal : public Terminal, private CdcAcmDevice {
|
||||
public:
|
||||
explicit UsbTerminal(const esp_modem_dte_config *config)
|
||||
{
|
||||
const struct esp_modem_usb_term_config* usb_config = (struct esp_modem_usb_term_config*)(config->extension_config);
|
||||
|
||||
// Install USB Host driver
|
||||
if (usb_config->install_usb_host) {
|
||||
const usb_host_config_t host_config = {
|
||||
.skip_phy_setup = false,
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
};
|
||||
throw_if_esp_fail(usb_host_install(&host_config), "USB Host install failed");
|
||||
ESP_LOGD(TAG, "USB Host installed");
|
||||
throw_if_false(pdTRUE == xTaskCreatePinnedToCore(usb_host_task, "usb_host", 4096, NULL, config->task_priority + 1, NULL, usb_config->xCoreID), "USB host task failed");
|
||||
}
|
||||
|
||||
// Install CDC-ACM driver
|
||||
const cdc_acm_host_driver_config_t esp_modem_cdc_acm_driver_config = {
|
||||
.driver_task_stack_size = config->task_stack_size,
|
||||
.driver_task_priority = config->task_priority,
|
||||
.xCoreID = (BaseType_t)usb_config->xCoreID
|
||||
};
|
||||
|
||||
// Silently continue of error: CDC-ACM driver might be already installed
|
||||
cdc_acm_host_install(&esp_modem_cdc_acm_driver_config);
|
||||
|
||||
// Open CDC-ACM device
|
||||
const cdc_acm_host_device_config_t esp_modem_cdc_acm_device_config = {
|
||||
.connection_timeout_ms = usb_config->timeout_ms,
|
||||
.out_buffer_size = config->dte_buffer_size,
|
||||
.event_cb = handle_notif,
|
||||
.data_cb = handle_rx,
|
||||
.user_arg = this
|
||||
};
|
||||
|
||||
if (usb_config->cdc_compliant) {
|
||||
throw_if_esp_fail(this->CdcAcmDevice::open(usb_config->vid, usb_config->pid,
|
||||
usb_config->interface_idx, &esp_modem_cdc_acm_device_config),
|
||||
"USB Device open failed");
|
||||
} else {
|
||||
throw_if_esp_fail(this->CdcAcmDevice::open_vendor_specific(usb_config->vid, usb_config->pid,
|
||||
usb_config->interface_idx, &esp_modem_cdc_acm_device_config),
|
||||
"USB Device open failed");
|
||||
}
|
||||
};
|
||||
|
||||
~UsbTerminal()
|
||||
{
|
||||
this->CdcAcmDevice::close();
|
||||
};
|
||||
|
||||
void start() override
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void stop() override
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int write(uint8_t *data, size_t len) override
|
||||
{
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, data, len, ESP_LOG_DEBUG);
|
||||
if (this->CdcAcmDevice::tx_blocking(data, len) != ESP_OK) {
|
||||
return -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int read(uint8_t *data, size_t len) override
|
||||
{
|
||||
// This function should never be called. UsbTerminal provides data through Terminal::on_read callback
|
||||
ESP_LOGW(TAG, "Unexpected call to UsbTerminal::read function");
|
||||
return -1;
|
||||
}
|
||||
|
||||
private:
|
||||
UsbTerminal() = delete;
|
||||
UsbTerminal(const UsbTerminal ©) = delete;
|
||||
UsbTerminal &operator=(const UsbTerminal ©) = delete;
|
||||
bool operator== (const UsbTerminal ¶m) const = delete;
|
||||
bool operator!= (const UsbTerminal ¶m) const = delete;
|
||||
|
||||
static void handle_rx(uint8_t *data, size_t data_len, void *user_arg)
|
||||
{
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, data, data_len, ESP_LOG_DEBUG);
|
||||
UsbTerminal *this_terminal = static_cast<UsbTerminal *>(user_arg);
|
||||
if (data_len > 0 && this_terminal->on_read) {
|
||||
this_terminal->on_read(data, data_len);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Unhandled RX data");
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_notif(cdc_acm_dev_hdl_t cdc_hdl, const cdc_acm_host_dev_event_data_t *event, void *user_ctx)
|
||||
{
|
||||
UsbTerminal *this_terminal = static_cast<UsbTerminal *>(user_ctx);
|
||||
|
||||
switch (event->type) {
|
||||
// Notifications like Ring, Rx Carrier indication or Network connection indication are not relevant for USB terminal
|
||||
case CDC_ACM_HOST_NETWORK_CONNECTION:
|
||||
case CDC_ACM_HOST_SERIAL_STATE:
|
||||
break;
|
||||
case CDC_ACM_HOST_DEVICE_DISCONNECTED:
|
||||
ESP_LOGW(TAG, "USB terminal disconnected");
|
||||
cdc_acm_host_close(cdc_hdl);
|
||||
if (this_terminal->on_error) {
|
||||
this_terminal->on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
|
||||
}
|
||||
break;
|
||||
case CDC_ACM_HOST_ERROR:
|
||||
ESP_LOGE(TAG, "Unexpected CDC-ACM error: %d.", event->data.error);
|
||||
if (this_terminal->on_error) {
|
||||
this_terminal->on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
std::unique_ptr<Terminal> create_usb_terminal(const esp_modem_dte_config *config)
|
||||
{
|
||||
TRY_CATCH_RET_NULL(
|
||||
return std::make_unique<UsbTerminal>(config);
|
||||
)
|
||||
}
|
||||
} // namespace esp_modem
|
@ -1,32 +0,0 @@
|
||||
// Copyright 2021-2022 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include "usb_terminal.hpp"
|
||||
#include "cxx_include/esp_modem_api.hpp"
|
||||
#include "cxx_include/esp_modem_netif.hpp"
|
||||
|
||||
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
static const char *TAG = "modem_usb_api_target";
|
||||
#endif
|
||||
|
||||
namespace esp_modem {
|
||||
std::shared_ptr<DTE> create_usb_dte(const dte_config *config)
|
||||
{
|
||||
TRY_CATCH_RET_NULL(
|
||||
auto term = create_usb_terminal(config);
|
||||
return std::make_shared<DTE>(config, std::move(term));
|
||||
)
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// Copyright 2021-2022 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
#include "cxx_include/esp_modem_dce.hpp"
|
||||
#include "cxx_include/esp_modem_dce_module.hpp"
|
||||
|
||||
namespace esp_modem {
|
||||
/**
|
||||
* @brief Create USB DTE
|
||||
*
|
||||
* @param config DTE configuration
|
||||
* @return shared ptr to DTE on success
|
||||
* nullptr on failure (either due to insufficient memory or wrong dte configuration)
|
||||
* if exceptions are disabled the API abort()'s on error
|
||||
*/
|
||||
std::shared_ptr<DTE> create_usb_dte(const dte_config *config);
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
// Copyright 2021-2022 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @brief USB configuration structure
|
||||
* @see USB host CDC-ACM driver documentation for details about interfaces settings
|
||||
*/
|
||||
struct esp_modem_usb_term_config {
|
||||
uint16_t vid; /*!< Vendor ID of the USB device */
|
||||
uint16_t pid; /*!< Product ID of the USB device */
|
||||
int interface_idx; /*!< USB Interface index that will be used */
|
||||
uint32_t timeout_ms; /*!< Time for a USB modem to connect to USB host. 0 means wait forever. */
|
||||
int xCoreID; /*!< Core affinity of created tasks: CDC-ACM driver task and optional USB Host task */
|
||||
bool cdc_compliant; /*!< Treat the USB device as CDC-compliant. Read CDC-ACM driver documentation for more details */
|
||||
bool install_usb_host; /*!< Flag whether USB Host driver should be installed */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief ESP Mode USB DTE Default Configuration
|
||||
*
|
||||
* @param[in] _usb_config esp_modem_usb_term_config configuration structure. Can be obtained by ESP_MODEM_DEFAULT_USB_CONFIG
|
||||
*
|
||||
*/
|
||||
#define ESP_MODEM_DTE_DEFAULT_USB_CONFIG(_usb_config) \
|
||||
{ \
|
||||
.dte_buffer_size = 512, \
|
||||
.task_stack_size = 4096, \
|
||||
.task_priority = 5, \
|
||||
.extension_config = &_usb_config \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ESP Modem USB Default Configuration
|
||||
*
|
||||
* @param[in] _vid USB Vendor ID
|
||||
* @param[in] _pid USB Product ID
|
||||
* @see USB host CDC-ACM driver documentation for details about interfaces settings
|
||||
*/
|
||||
#define ESP_MODEM_DEFAULT_USB_CONFIG(_vid, _pid) \
|
||||
{ \
|
||||
.vid = _vid, \
|
||||
.pid = _pid, \
|
||||
.interface_idx = 0, \
|
||||
.timeout_ms = 0, \
|
||||
.xCoreID = 0, \
|
||||
.cdc_compliant = false, \
|
||||
.install_usb_host = true \
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
// Copyright 2021 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
struct esp_modem_dte_config;
|
||||
|
||||
// Copy-pasted from esp_modem/private_include/exception_stub.hpp
|
||||
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
#define TRY_CATCH_OR_DO(block, action) \
|
||||
try { block \
|
||||
} catch (std::bad_alloc& e) { \
|
||||
ESP_LOGE(TAG, "Out of memory"); \
|
||||
action; \
|
||||
} catch (::esp_modem::esp_err_exception& e) { \
|
||||
esp_err_t err = e.get_err_t(); \
|
||||
ESP_LOGE(TAG, "%s: Exception caught with ESP err_code=%d", __func__, err); \
|
||||
ESP_LOGE(TAG, "%s", e.what()); \
|
||||
action; \
|
||||
}
|
||||
|
||||
#define TRY_CATCH_RET_NULL(block) TRY_CATCH_OR_DO(block, return nullptr)
|
||||
#else
|
||||
|
||||
#define TRY_CATCH_OR_DO(block, action) \
|
||||
block
|
||||
|
||||
#define TRY_CATCH_RET_NULL(block) \
|
||||
block
|
||||
|
||||
#endif
|
||||
|
||||
namespace esp_modem {
|
||||
|
||||
std::unique_ptr<Terminal> create_usb_terminal(const esp_modem_dte_config *config);
|
||||
|
||||
} // namespace esp_modem
|
@ -2,6 +2,6 @@ idf_component_register(SRCS "modem_console_main.cpp"
|
||||
"console_helper.cpp"
|
||||
"httpget_handle.c"
|
||||
"ping_handle.c"
|
||||
REQUIRES console esp_http_client nvs_flash esp_modem esp_modem_usb_dte
|
||||
REQUIRES console esp_http_client nvs_flash
|
||||
INCLUDE_DIRS ".")
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
|
@ -14,4 +14,159 @@ menu "Example Configuration"
|
||||
help
|
||||
Connect to modem via USB (CDC-ACM class). For IDF version >= 4.4.
|
||||
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_SHINY
|
||||
bool "SHINY"
|
||||
help
|
||||
SHINY is a GSM/GPRS module.
|
||||
It supports SHINY.
|
||||
config EXAMPLE_MODEM_DEVICE_SIM800
|
||||
bool "SIM800"
|
||||
help
|
||||
SIMCom SIM800L is a GSM/GPRS module.
|
||||
It supports Quad-band 850/900/1800/1900MHz.
|
||||
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_SIM7000
|
||||
bool "SIM7000"
|
||||
help
|
||||
SIM7000 is a Multi-Band LTE-FDD and GSM/GPRS/EDGE module.
|
||||
config EXAMPLE_MODEM_DEVICE_SIM7070
|
||||
bool "SIM7070"
|
||||
help
|
||||
SIM7070 is Multi-Band CAT M and NB IoT module.
|
||||
config EXAMPLE_MODEM_DEVICE_SIM7600
|
||||
bool "SIM7600"
|
||||
help
|
||||
SIM7600 is a Multi-Band LTE-TDD/LTE-FDD/HSPA+ and GSM/GPRS/EDGE module.
|
||||
endchoice
|
||||
|
||||
config EXAMPLE_MODEM_PPP_APN
|
||||
string "Set MODEM APN"
|
||||
default "internet"
|
||||
help
|
||||
Set APN (Access Point Name), a logical name to choose data network
|
||||
|
||||
config EXAMPLE_MODEM_PPP_AUTH_USERNAME
|
||||
string "Set username for authentication"
|
||||
default "espressif"
|
||||
depends on !EXAMPLE_MODEM_PPP_AUTH_NONE
|
||||
help
|
||||
Set username for PPP Authentication.
|
||||
|
||||
config EXAMPLE_MODEM_PPP_AUTH_PASSWORD
|
||||
string "Set password for authentication"
|
||||
default "esp32"
|
||||
depends on !EXAMPLE_MODEM_PPP_AUTH_NONE
|
||||
help
|
||||
Set password for PPP Authentication.
|
||||
|
||||
config EXAMPLE_MODEM_PPP_AUTH_NONE
|
||||
bool "Skip PPP authentication"
|
||||
default n
|
||||
help
|
||||
Set to true for the PPP client to skip authentication
|
||||
|
||||
menu "UART Configuration"
|
||||
depends on EXAMPLE_SERIAL_CONFIG_UART
|
||||
|
||||
choice EXAMPLE_FLOW_CONTROL
|
||||
bool "Set preferred modem control flow"
|
||||
default EXAMPLE_FLOW_CONTROL_NONE
|
||||
help
|
||||
Set the modem's preferred control flow
|
||||
|
||||
config EXAMPLE_FLOW_CONTROL_NONE
|
||||
bool "No control flow"
|
||||
config EXAMPLE_FLOW_CONTROL_SW
|
||||
bool "SW control flow"
|
||||
config EXAMPLE_FLOW_CONTROL_HW
|
||||
bool "HW control flow"
|
||||
endchoice
|
||||
|
||||
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 4096
|
||||
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
|
||||
|
||||
config EXAMPLE_MODEM_PWRKEY_PIN
|
||||
int "PWRKEY Pin Number"
|
||||
default 18
|
||||
range 0 31
|
||||
help
|
||||
Pin number connected to modem's power key pin.
|
||||
endmenu
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* Modem console example
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* Modem console example
|
||||
*/
|
||||
|
||||
#include "console_helper.hpp"
|
||||
@ -18,6 +19,16 @@ ConsoleCommand::ConsoleCommand(const char *command, const char *help, const std:
|
||||
RegisterCommand(command, help, args);
|
||||
}
|
||||
|
||||
ConsoleCommand::~ConsoleCommand()
|
||||
{
|
||||
// Find this command in static list of commands and remove it
|
||||
auto cmd = std::find(console_commands.begin(), console_commands.end(), this);
|
||||
if (cmd != console_commands.end()) {
|
||||
console_commands.erase(cmd);
|
||||
last_command--;
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleCommand::RegisterCommand(const char *command, const char *help, const std::vector<CommandArgs> &args)
|
||||
{
|
||||
assert(last_command <= MAX_REPEAT_NR);
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* Modem console example
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* Modem console example
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -92,6 +93,11 @@ public:
|
||||
*/
|
||||
explicit ConsoleCommand(const char *command, const char *help, const std::vector<CommandArgs> &args, std::function<bool(ConsoleCommand *)> f);
|
||||
|
||||
/**
|
||||
* @brief Destructor of ConsoleCommand
|
||||
*/
|
||||
~ConsoleCommand();
|
||||
|
||||
/**
|
||||
* @brief Utility getters of various params from the argument list
|
||||
*/
|
||||
|
@ -1,10 +1,12 @@
|
||||
/* Modem console example
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* Modem console example
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -0,0 +1,12 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
## Required IDF version
|
||||
idf: ">=4.1.0"
|
||||
espressif/esp_modem:
|
||||
version: "^0.1.20"
|
||||
override_path: "../../../"
|
||||
espressif/esp_modem_usb_dte:
|
||||
version: "^1.0.0"
|
||||
rules:
|
||||
- if: "idf_version >=4.4"
|
||||
- if: "target in [esp32s2, esp32s3]"
|
@ -1,10 +1,11 @@
|
||||
/* Modem console example
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* Modem console example
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
@ -15,10 +16,12 @@
|
||||
#include "esp_console.h"
|
||||
#include "esp_event.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "esp_modem_config.h"
|
||||
#include "cxx_include/esp_modem_api.hpp"
|
||||
#if defined(CONFIG_USB_OTG_SUPPORTED)
|
||||
#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
|
||||
#include "esp_modem_usb_config.h"
|
||||
#include "cxx_include/esp_modem_usb_api.hpp"
|
||||
#endif
|
||||
@ -26,6 +29,14 @@
|
||||
#include "console_helper.hpp"
|
||||
#include "my_module_dce.hpp"
|
||||
|
||||
#if defined(CONFIG_EXAMPLE_FLOW_CONTROL_NONE)
|
||||
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_NONE
|
||||
#elif defined(CONFIG_EXAMPLE_FLOW_CONTROL_SW)
|
||||
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_SW
|
||||
#elif defined(CONFIG_EXAMPLE_FLOW_CONTROL_HW)
|
||||
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_HW
|
||||
#endif
|
||||
|
||||
#define CHECK_ERR(cmd, success_action) do { \
|
||||
auto err = cmd; \
|
||||
if (err == command_result::OK) { \
|
||||
@ -41,6 +52,9 @@
|
||||
*/
|
||||
#define DEFAULT_APN "my_apn"
|
||||
|
||||
#define GPIO_OUTPUT_PWRKEY (gpio_num_t)CONFIG_EXAMPLE_MODEM_PWRKEY_PIN
|
||||
#define GPIO_OUTPUT_PIN_SEL (1ULL<<GPIO_OUTPUT_PWRKEY)
|
||||
|
||||
extern "C" void modem_console_register_http(void);
|
||||
extern "C" void modem_console_register_ping(void);
|
||||
|
||||
@ -48,10 +62,40 @@ static const char *TAG = "modem_console";
|
||||
static esp_console_repl_t *s_repl = nullptr;
|
||||
|
||||
using namespace esp_modem;
|
||||
static SignalGroup exit_signal;
|
||||
|
||||
|
||||
void config_gpio(void)
|
||||
{
|
||||
gpio_config_t io_conf = {}; //zero-initialize the config structure.
|
||||
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
|
||||
io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode
|
||||
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; //bit mask of the pins that you want to set,e.g.GPIO18/19
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; //disable pull-down mode
|
||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE; //disable pull-up mode
|
||||
|
||||
gpio_config(&io_conf); //configure GPIO with the given settings
|
||||
}
|
||||
|
||||
void wakeup_modem(void)
|
||||
{
|
||||
/* Power on the modem */
|
||||
ESP_LOGI(TAG, "Power on the modem");
|
||||
gpio_set_level(GPIO_OUTPUT_PWRKEY, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
gpio_set_level(GPIO_OUTPUT_PWRKEY, 0);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
}
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
static RTC_RODATA_ATTR char apn_rtc[20] = DEFAULT_APN;
|
||||
static RTC_DATA_ATTR modem_mode mode_rtc = esp_modem::modem_mode::COMMAND_MODE;
|
||||
|
||||
config_gpio();
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
@ -64,16 +108,57 @@ extern "C" void app_main(void)
|
||||
|
||||
#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_UART)
|
||||
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.flow_control = EXAMPLE_FLOW_CONTROL;
|
||||
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;
|
||||
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 uart_dte = create_uart_dte(&dte_config);
|
||||
|
||||
#if CONFIG_EXAMPLE_MODEM_DEVICE_SHINY == 1
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for the SIM7600 module...");
|
||||
auto dce = create_SIM7600_dce(&dce_config, uart_dte, esp_netif);
|
||||
#else
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for a generic module...");
|
||||
auto dce = create_generic_dce(&dce_config, uart_dte, esp_netif);
|
||||
#endif
|
||||
|
||||
|
||||
#elif defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
|
||||
struct esp_modem_usb_term_config usb_config = ESP_MODEM_DEFAULT_USB_CONFIG(0x2C7C, 0x0296); // VID and PID of BG96 modem
|
||||
// BG96 modem implements Vendor Specific class, that is CDC-ACM like. Interface for AT commands has index no. 2.
|
||||
usb_config.interface_idx = 2;
|
||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_USB_CONFIG(usb_config);
|
||||
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
|
||||
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);
|
||||
dte->set_error_cb([&](terminal_error err) {
|
||||
ESP_LOGI(TAG, "error handler %d", err);
|
||||
if (err == terminal_error::DEVICE_GONE) {
|
||||
exit_signal.set(1);
|
||||
}
|
||||
});
|
||||
std::unique_ptr<DCE> dce = create_BG96_dce(&dce_config, dte, esp_netif);
|
||||
|
||||
#else
|
||||
@ -82,11 +167,39 @@ extern "C" void app_main(void)
|
||||
|
||||
assert(dce != nullptr);
|
||||
|
||||
if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
|
||||
if (command_result::OK != dce->set_flow_control(2, 2)) {
|
||||
ESP_LOGE(TAG, "Failed to set the set_flow_control mode");
|
||||
return;
|
||||
}
|
||||
ESP_LOGI(TAG, "set_flow_control OK");
|
||||
}
|
||||
|
||||
// init console REPL environment
|
||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
||||
|
||||
switch (esp_sleep_get_wakeup_cause()) {
|
||||
case ESP_SLEEP_WAKEUP_TIMER:
|
||||
if (esp_modem::modem_mode::CMUX_MODE == mode_rtc) {
|
||||
ESP_LOGI(TAG, "Deep sleep reset\n");
|
||||
|
||||
/* Set APN */
|
||||
auto new_pdp = std::unique_ptr<PdpContext>(new PdpContext(apn_rtc));
|
||||
dce->get_module()->configure_pdp_context(std::move(new_pdp));
|
||||
|
||||
/* Set CMUX mode */
|
||||
if (!dce->set_mode(mode_rtc)) {
|
||||
ESP_LOGE(TAG, "Failed to set the desired mode");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ESP_SLEEP_WAKEUP_UNDEFINED:
|
||||
default:
|
||||
ESP_LOGD(TAG, "Not a deep sleep reset\n");
|
||||
}
|
||||
|
||||
modem_console_register_http();
|
||||
modem_console_register_ping();
|
||||
const struct SetModeArgs {
|
||||
@ -97,12 +210,25 @@ extern "C" void app_main(void)
|
||||
if (c->get_count_of(&SetModeArgs::mode)) {
|
||||
auto mode = c->get_string_of(&SetModeArgs::mode);
|
||||
modem_mode dev_mode;
|
||||
if (mode == "CMD") {
|
||||
if (mode == "CMUX1") {
|
||||
dev_mode = esp_modem::modem_mode::CMUX_MANUAL_MODE;
|
||||
} else if (mode == "CMUX2") {
|
||||
dev_mode = esp_modem::modem_mode::CMUX_MANUAL_EXIT;
|
||||
} else if (mode == "CMUX3") {
|
||||
dev_mode = esp_modem::modem_mode::CMUX_MANUAL_SWAP;
|
||||
} else if (mode == "CMUX4") {
|
||||
dev_mode = esp_modem::modem_mode::CMUX_MANUAL_DATA;
|
||||
} else if (mode == "CMUX5") {
|
||||
dev_mode = esp_modem::modem_mode::CMUX_MANUAL_COMMAND;
|
||||
} else if (mode == "CMD") {
|
||||
dev_mode = esp_modem::modem_mode::COMMAND_MODE;
|
||||
} else if (mode == "PPP") {
|
||||
dev_mode = esp_modem::modem_mode::DATA_MODE;
|
||||
} else if (mode == "CMUX") {
|
||||
/* Even if switching to CMUX fails, we make the DTE multiplex terminal.
|
||||
(This is potentially a bug and might be fixed eventually) */
|
||||
dev_mode = esp_modem::modem_mode::CMUX_MODE;
|
||||
mode_rtc = dev_mode;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Unsupported mode: %s", mode.c_str());
|
||||
return 1;
|
||||
@ -112,6 +238,8 @@ extern "C" void app_main(void)
|
||||
ESP_LOGE(TAG, "Failed to set the desired mode");
|
||||
return 1;
|
||||
}
|
||||
mode_rtc = dev_mode;
|
||||
|
||||
ESP_LOGI(TAG, "OK");
|
||||
}
|
||||
return 0;
|
||||
@ -219,6 +347,7 @@ extern "C" void app_main(void)
|
||||
if (c->get_count_of(&SetApn::apn)) {
|
||||
auto apn = c->get_string_of(&SetApn::apn);
|
||||
ESP_LOGI(TAG, "Setting the APN=%s...", apn.c_str());
|
||||
strcpy(apn_rtc, apn.c_str());
|
||||
auto new_pdp = std::unique_ptr<PdpContext>(new PdpContext(apn));
|
||||
dce->get_module()->configure_pdp_context(std::move(new_pdp));
|
||||
ESP_LOGI(TAG, "OK");
|
||||
@ -226,16 +355,96 @@ extern "C" void app_main(void)
|
||||
return 0;
|
||||
});
|
||||
|
||||
SignalGroup exit_signal;
|
||||
const ConsoleCommand ExitConsole("exit", "exit the console application", no_args, [&](ConsoleCommand * c) {
|
||||
ESP_LOGI(TAG, "Exiting...");
|
||||
exit_signal.set(1);
|
||||
s_repl->del(s_repl);
|
||||
return 0;
|
||||
});
|
||||
|
||||
/* Put the esp32 into deep sleep */
|
||||
const struct DeepSleepArgs {
|
||||
DeepSleepArgs(): timeout(INT1, nullptr, nullptr, "<tout>", "TIMEOUT") {}
|
||||
CommandArgs timeout;
|
||||
} deep_sleep_args;
|
||||
const ConsoleCommand SetDeepSleep("set_deep_sleep", "Put esp32 to deep sleep", &deep_sleep_args, sizeof(deep_sleep_args), [&](ConsoleCommand * c) {
|
||||
int tout = c->get_int_of(&DeepSleepArgs::timeout);
|
||||
ESP_LOGI(TAG, "Entering deep sleep for %d sec", tout);
|
||||
ESP_LOGI(TAG, "Wakeup Cause: %d ", esp_sleep_get_wakeup_cause());
|
||||
esp_deep_sleep(tout * 1000000);
|
||||
return 0;
|
||||
});
|
||||
|
||||
/* Wake up modem */
|
||||
const ConsoleCommand WakeupModem("wakeup_modem", "Wakes up the modem from PSM", no_args, [&](ConsoleCommand * c) {
|
||||
wakeup_modem();
|
||||
ESP_LOGI(TAG, "OK");
|
||||
return 0;
|
||||
});
|
||||
|
||||
/* Enable PSM modem */
|
||||
const ConsoleCommand EnablePSM("enable_psm", "Enables PSM on the modem", no_args, [&](ConsoleCommand * c) {
|
||||
std::string out;
|
||||
CHECK_ERR(dce->at("AT+CPSMS=1", out, 500), ESP_LOGI(TAG, "OK. %s", out.c_str()));
|
||||
return 0;
|
||||
});
|
||||
|
||||
/* Disable PSM modem */
|
||||
const ConsoleCommand DisablePSM("disable_psm", "Disables PSM on the modem", no_args, [&](ConsoleCommand * c) {
|
||||
std::string out;
|
||||
CHECK_ERR(dce->at("AT+CPSMS=0", out, 500), ESP_LOGI(TAG, "OK. %s", out.c_str()));
|
||||
return 0;
|
||||
});
|
||||
|
||||
/* Get modem PSM cfg */
|
||||
const ConsoleCommand GetModemCfg("get_psm_cfg", "Get PSM config", no_args, [&](ConsoleCommand * c) {
|
||||
std::string out;
|
||||
CHECK_ERR(dce->at("AT+CPSMS?", out, 500), ESP_LOGI(TAG, "OK. %s", out.c_str()));
|
||||
return 0;
|
||||
});
|
||||
|
||||
/* Set modem PSM config */
|
||||
const struct SetPsmCfgArgs {
|
||||
SetPsmCfgArgs():
|
||||
periodic_tau(STR1, nullptr, nullptr, "<Requested_Periodic-TAU>", "T3412 Timer in 8-bit format"),
|
||||
active_time(STR0, nullptr, nullptr, "<Requested_Active-Time>", "T3324 Timer in 8-bit format") {}
|
||||
CommandArgs periodic_tau;
|
||||
CommandArgs active_time;
|
||||
} set_psm_cfg_args;
|
||||
const ConsoleCommand SetPsmCfg("set_psm_cfg", "Set PSM config", &set_psm_cfg_args, sizeof(set_psm_cfg_args), [&](ConsoleCommand * c) {
|
||||
std::string out;
|
||||
auto periodic_tau = c->get_string_of(&SetPsmCfgArgs::periodic_tau);
|
||||
auto active_time = c->get_string_of(&SetPsmCfgArgs::active_time);
|
||||
|
||||
/* Validate input */
|
||||
if ((strlen(periodic_tau.c_str()) != strlen("00000000")) ||
|
||||
(strlen(active_time.c_str()) != strlen("00000000"))) {
|
||||
ESP_LOGE(TAG, "Failed with ERROR: Invalid argument length");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get PSM config */
|
||||
dce->at("AT+CPSMS?", out, 500);
|
||||
|
||||
/* Update PSM config */
|
||||
if (out.size() > 8) {
|
||||
std::string set_cmd = "AT+CPSMS=" + std::to_string(out.c_str()[8] - '0') + ",,,\"" + periodic_tau.c_str() + "\",\"" + active_time.c_str() + "\"";
|
||||
CHECK_ERR(dce->at(set_cmd, out, 500), ESP_LOGI(TAG, "OK. %s", out.c_str()));
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed with ERROR: Invalid AT+CPSMS? return length");
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
||||
// start console REPL
|
||||
ESP_ERROR_CHECK(esp_console_start_repl(s_repl));
|
||||
// wait for exit
|
||||
exit_signal.wait_any(1, UINT32_MAX);
|
||||
s_repl->del(s_repl);
|
||||
ESP_LOGI(TAG, "Exiting...%d", esp_get_free_heap_size());
|
||||
#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
|
||||
// USB example runs in a loop to demonstrate hot-plugging and sudden disconnection features.
|
||||
} // while (1)
|
||||
#endif
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* Modem console example: Custom DCE
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
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.
|
||||
/*
|
||||
* Modem console example: Custom DCE
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@ -1,10 +1,10 @@
|
||||
/* Ping handle 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
/*
|
||||
* Ping handle example
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -0,0 +1 @@
|
||||
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y
|
@ -1,8 +1,7 @@
|
||||
# Override some defaults to enable PPP
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=7168
|
||||
CONFIG_LWIP_PPP_SUPPORT=y
|
||||
# CONFIG_LWIP_PPP_ENABLE_IPV6 is not set
|
||||
CONFIG_LWIP_PPP_PAP_SUPPORT=y
|
||||
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
||||
# Do not enable IPV6 in dte<->dce link local
|
||||
CONFIG_LWIP_PPP_ENABLE_IPV6=n
|
||||
# Disable legacy API
|
||||
CONFIG_MODEM_LEGACY_API=n
|
||||
|
10
components/esp_modem/examples/modem_psm/CMakeLists.txt
Normal file
10
components/esp_modem/examples/modem_psm/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# For more information about build system see
|
||||
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||
# The following five 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.16)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS "../..")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(modem_psm)
|
32
components/esp_modem/examples/modem_psm/README.md
Normal file
32
components/esp_modem/examples/modem_psm/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
# Modem Power Saving Mode, sleep modes example
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
This example demonstrates Power Saving Mode(PSM) in Sim70XX modems along with Deep sleep and Light Sleep modes in esp32.
|
||||
This example enables Power saving mode in Sim70XX modem and tries to synchronise the sleep cycle of the modem with esp32.
|
||||
When the modem wakes up from PSM sleep it wakes up the esp32. While the modem is awake esp32 goes to light sleep.
|
||||
|
||||
This example is tested on a SIM7080 modem.
|
||||
|
||||
## Supported devices
|
||||
|
||||
This example is supported only on ESP32, ESP32-S2 and ESP32-S3.
|
||||
|
||||
## Configuration
|
||||
|
||||
* EXAMPLE_MODEM_UART_TX_PIN: Connect this pin to the UART Tx pin of the modem.
|
||||
* EXAMPLE_MODEM_UART_RX_PIN: Connect this pin to the UART Rx pin of the modem.
|
||||
* EXAMPLE_MODEM_PWRKEY_PIN: Connect this pin to the PWRKEY pin of the modem.
|
||||
* EXAMPLE_MODEM_STATUS_PIN: Connect this pin to the Status pin of the modem.
|
||||
|
||||
The status pin might not be exposed on a modem. It needs to tapped out from the LED indicator marked as STS.
|
||||
|
||||
* EXAMPLE_MODEM_LIGHT_SLEEP_DURATION: Duration for which the esp32 will go into light sleep, while the modem is awake.
|
||||
|
||||
If the esp32 goes into deep sleep while the modem is awake, esp32 will be awaken by the STATUS pin. So it's recommended to go to light sleep while the modem is awake.
|
||||
|
||||
* EXAMPLE_MODEM_T3412_PERIODIC_TAU: T3412 timer is the duration of one awake and sleep cycle of the modem in PSM.
|
||||
* EXAMPLE_MODEM_T3324_ACTIVE_TIME: T3324 timer is the duration for which the modem stays PSM.
|
||||
|
||||
The timeout information is coded in bit format for T3412 and T3324 timer.
|
@ -0,0 +1,3 @@
|
||||
|
||||
idf_component_register(SRCS "modem_psm.c"
|
||||
INCLUDE_DIRS ".")
|
109
components/esp_modem/examples/modem_psm/main/Kconfig.projbuild
Normal file
109
components/esp_modem/examples/modem_psm/main/Kconfig.projbuild
Normal file
@ -0,0 +1,109 @@
|
||||
|
||||
menu "Example Configuration"
|
||||
|
||||
choice EXAMPLE_MODEM_DEVICE
|
||||
prompt "Choose supported modem device (DCE)"
|
||||
default EXAMPLE_MODEM_DEVICE_SIM7080
|
||||
help
|
||||
Select modem device connected to the ESP DTE.
|
||||
config EXAMPLE_MODEM_DEVICE_SIM7070
|
||||
bool "SIM7070"
|
||||
help
|
||||
SIM7070 is Multi-Band CAT M and NB IoT module.
|
||||
config EXAMPLE_MODEM_DEVICE_SIM7080
|
||||
bool "SIM7080"
|
||||
help
|
||||
SIM7080 is Multi-Band CAT M and NB IoT module.
|
||||
endchoice
|
||||
|
||||
menu "UART Configuration"
|
||||
config EXAMPLE_MODEM_UART_TX_PIN
|
||||
int "TXD Pin Number"
|
||||
default 4
|
||||
range 0 31
|
||||
help
|
||||
Pin number of UART TX.
|
||||
|
||||
config EXAMPLE_MODEM_UART_RX_PIN
|
||||
int "RXD Pin Number"
|
||||
default 5
|
||||
range 0 31
|
||||
help
|
||||
Pin number of UART RX.
|
||||
|
||||
config EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE
|
||||
int "UART Event Task Stack Size"
|
||||
range 2000 6000
|
||||
default 4096
|
||||
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_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
|
||||
|
||||
config EXAMPLE_MODEM_PWRKEY_PIN
|
||||
int "PWRKEY Pin Number"
|
||||
default 18
|
||||
range 0 31
|
||||
help
|
||||
Pin number connected to modem's power key pin.
|
||||
|
||||
config EXAMPLE_MODEM_STATUS_PIN
|
||||
int "STATUS Pin Number"
|
||||
default 19
|
||||
range 0 31
|
||||
help
|
||||
Pin number connected to modem's status pin.
|
||||
|
||||
config EXAMPLE_MODEM_LIGHT_SLEEP_DURATION
|
||||
int "Light Sleep Duration"
|
||||
default 10
|
||||
range 0 15000
|
||||
help
|
||||
Duration in seconds, of which the esp32 goes into light sleep while the modem is awake.
|
||||
|
||||
config EXAMPLE_MODEM_PPP_APN
|
||||
string "Set MODEM APN"
|
||||
default "internet"
|
||||
help
|
||||
Set APN (Access Point Name), a logical name to choose data network
|
||||
|
||||
config EXAMPLE_MODEM_T3412_PERIODIC_TAU
|
||||
string "T3412 Requester Periodic TAU"
|
||||
default "00000100"
|
||||
help
|
||||
T3412 timer, i.e the duration of one awake and sleep cycle of the modem in PSM.
|
||||
|
||||
config EXAMPLE_MODEM_T3324_ACTIVE_TIME
|
||||
string "T3324 Requester Active Time"
|
||||
default "00000001"
|
||||
help
|
||||
T3324 timer, i.e the duration for which the modem stays PSM.
|
||||
|
||||
endmenu
|
202
components/esp_modem/examples/modem_psm/main/modem_psm.c
Normal file
202
components/esp_modem/examples/modem_psm/main/modem_psm.c
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Power Saving Mode(PSM) in Sim70XX modems along with
|
||||
* Deep sleep and Light Sleep modes in esp32.
|
||||
*/
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/uart.h"
|
||||
#include "string.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "esp_modem_api.h"
|
||||
#include "esp_event.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
#define TXD_PIN ((gpio_num_t)CONFIG_EXAMPLE_MODEM_UART_TX_PIN)
|
||||
#define RXD_PIN ((gpio_num_t)CONFIG_EXAMPLE_MODEM_UART_RX_PIN)
|
||||
#define GPIO_INPUT_STATUS ((gpio_num_t)CONFIG_EXAMPLE_MODEM_STATUS_PIN)
|
||||
#define GPIO_OUTPUT_PWRKEY ((gpio_num_t)CONFIG_EXAMPLE_MODEM_PWRKEY_PIN)
|
||||
#define GPIO_OUTPUT_PIN_SEL (1ULL<<GPIO_OUTPUT_PWRKEY)
|
||||
|
||||
#define CHECK_ERR(cmd, success_action) do { \
|
||||
esp_err_t ret = cmd; \
|
||||
if (ret == ESP_OK) { \
|
||||
success_action; \
|
||||
} else { \
|
||||
ESP_LOGE(TAG, "Failed with %s", ret == ESP_ERR_TIMEOUT ? "TIMEOUT":"ERROR"); \
|
||||
} } while (0)
|
||||
|
||||
|
||||
const char *TAG = "modem_psm";
|
||||
RTC_DATA_ATTR static int boot_count = 0;
|
||||
|
||||
|
||||
void dce_init(esp_modem_dce_t **dce, esp_netif_t **esp_netif)
|
||||
{
|
||||
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_PPP_APN);
|
||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||
esp_netif_config_t netif_ppp_config = ESP_NETIF_DEFAULT_PPP();
|
||||
*esp_netif = esp_netif_new(&netif_ppp_config);
|
||||
assert(*esp_netif);
|
||||
|
||||
/* 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.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;
|
||||
dte_config.task_priority = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY;
|
||||
dte_config.dte_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE / 2;
|
||||
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for a generic module...");
|
||||
*dce = esp_modem_new(&dte_config, &dce_config, *esp_netif);
|
||||
assert(*dce);
|
||||
}
|
||||
|
||||
void config_pwrkey_gpio(void)
|
||||
{
|
||||
gpio_config_t io_conf = {}; //zero-initialize the config structure.
|
||||
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
|
||||
io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode
|
||||
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; //bit mask of the pins that you want to set,e.g.GPIO18/19
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; //disable pull-down mode
|
||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE; //disable pull-up mode
|
||||
|
||||
gpio_config(&io_conf); //configure GPIO with the given settings
|
||||
}
|
||||
|
||||
void power_on_modem(esp_modem_dce_t *dce)
|
||||
{
|
||||
rtc_gpio_hold_dis(GPIO_OUTPUT_PWRKEY);
|
||||
|
||||
/* Power on the modem */
|
||||
ESP_LOGI(TAG, "Power on the modem");
|
||||
gpio_set_level(GPIO_OUTPUT_PWRKEY, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
gpio_set_level(GPIO_OUTPUT_PWRKEY, 0);
|
||||
|
||||
rtc_gpio_hold_en(GPIO_OUTPUT_PWRKEY);
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
|
||||
CHECK_ERR(esp_modem_sync(dce), ESP_LOGI(TAG, "OK"));
|
||||
}
|
||||
|
||||
void power_down_modem(esp_modem_dce_t *dce)
|
||||
{
|
||||
char data[BUF_SIZE];
|
||||
|
||||
ESP_LOGI(TAG, "Power down the modem");
|
||||
|
||||
/* Power down the modem by AT command */
|
||||
CHECK_ERR(esp_modem_at(dce, "AT+CPOWD=1", data, 500), ESP_LOGI(TAG, "OK. %s", data));
|
||||
}
|
||||
|
||||
void run_at(esp_modem_dce_t *dce, uint8_t count)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
CHECK_ERR(esp_modem_sync(dce), ESP_LOGI(TAG, "OK"));
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
|
||||
void run_at_ping(esp_modem_dce_t *dce)
|
||||
{
|
||||
char data[BUF_SIZE];
|
||||
int rssi, ber;
|
||||
CHECK_ERR(esp_modem_get_signal_quality(dce, &rssi, &ber), ESP_LOGI(TAG, "OK. rssi=%d, ber=%d", rssi, ber));
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
CHECK_ERR(esp_modem_at(dce, "AT+CPSMS?", data, 500), ESP_LOGI(TAG, "OK. %s", data));
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
CHECK_ERR(esp_modem_at(dce, "AT+CPSI?", data, 500), ESP_LOGI(TAG, "OK. %s", data)); // Inquiring UE system information
|
||||
CHECK_ERR(esp_modem_at(dce, "AT+CNACT=0,1", data, 500), ESP_LOGI(TAG, "OK. %s", data)); // Activate the APP network
|
||||
CHECK_ERR(esp_modem_at(dce, "AT+SNPDPID=0", data, 500), ESP_LOGI(TAG, "OK. %s", data)); // Select PDP index for PING
|
||||
CHECK_ERR(esp_modem_at(dce, "AT+SNPING4=\"8.8.8.8\",3,16,1000", data, 500), ESP_LOGI(TAG, "OK. %s", data)); // Send IPv4 PING
|
||||
CHECK_ERR(esp_modem_at(dce, "AT+CNACT=0,0", data, 500), ESP_LOGI(TAG, "OK. %s", data)); // Deactivate the APP network
|
||||
}
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
char *cmd;
|
||||
char data[BUF_SIZE];
|
||||
esp_modem_dce_t *dce = NULL;
|
||||
esp_netif_t *esp_netif = NULL;
|
||||
esp_sleep_wakeup_cause_t wakeup_cause = esp_sleep_get_wakeup_cause();
|
||||
ESP_LOGI(TAG, "Deep sleep Wake Up Cause: %d\n", wakeup_cause);
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
dce_init(&dce, &esp_netif);
|
||||
|
||||
switch (wakeup_cause) {
|
||||
case ESP_SLEEP_WAKEUP_UNDEFINED:
|
||||
/* Power on the modem */
|
||||
config_pwrkey_gpio();
|
||||
power_on_modem(dce);
|
||||
|
||||
run_at(dce, 3);
|
||||
|
||||
/* Configure Power Saving Mode in the modem */
|
||||
asprintf(&cmd, "AT+CPSMS=1,,,\"%s\",\"%s\"\r\n", CONFIG_EXAMPLE_MODEM_T3412_PERIODIC_TAU,
|
||||
CONFIG_EXAMPLE_MODEM_T3324_ACTIVE_TIME);
|
||||
CHECK_ERR(esp_modem_at(dce, cmd, data, 500), ESP_LOGI(TAG, "OK. %s", data));
|
||||
free(cmd);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
/* Perform Communication tasks */
|
||||
run_at_ping(dce);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
break;
|
||||
|
||||
case ESP_SLEEP_WAKEUP_EXT0:
|
||||
run_at(dce, 3);
|
||||
|
||||
/* Perform Communication tasks */
|
||||
run_at_ping(dce);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Not a deep sleep reset: %d\n", wakeup_cause);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Light sleep before going to Deep sleep\n\n");
|
||||
|
||||
/* Enter light sleep mode as long as the modem is awake */
|
||||
esp_sleep_enable_timer_wakeup(CONFIG_EXAMPLE_MODEM_LIGHT_SLEEP_DURATION * 1000000);
|
||||
esp_light_sleep_start();
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); // Disabling timer before going to deep sleep.
|
||||
wakeup_cause = esp_sleep_get_wakeup_cause();
|
||||
ESP_LOGI(TAG, "Light sleep wakeup cause: %d\n", wakeup_cause);
|
||||
|
||||
/* DCE and netif clean-up */
|
||||
/* In Deep-sleep mode, the CPUs, most of the RAM, and all digital peripherals are powered off.
|
||||
* So dce and netif would be lost anyway if they are not explicitly destroyed.
|
||||
* But since dce is also linked with UART communication with the modem it's better to exit gracefully before going to deep sleep.
|
||||
*/
|
||||
esp_modem_destroy(dce);
|
||||
esp_netif_destroy(esp_netif);
|
||||
|
||||
/* Enable wakeup if status pin is high */
|
||||
esp_sleep_enable_ext0_wakeup(GPIO_INPUT_STATUS, 1);
|
||||
|
||||
ESP_LOGI(TAG, "Entering deep sleep: %d\n", boot_count++);
|
||||
esp_deep_sleep_start();
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
CONFIG_LWIP_PPP_SUPPORT=y
|
@ -6,5 +6,3 @@ set(EXTRA_COMPONENT_DIRS "../..")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(pppos_client)
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user