forked from espressif/esp-protocols
Compare commits
75 Commits
console_si
...
websocket-
Author | SHA1 | Date | |
---|---|---|---|
3f49583761 | |||
c6448c3bd1 | |||
f523b4dc84 | |||
6fda4c134e | |||
ba33588008 | |||
9758379921 | |||
f52a38ba34 | |||
74fc228cdf | |||
b176d3abbb | |||
f9e0281a04 | |||
9c555b90d4 | |||
7babdeb970 | |||
7faa97450b | |||
cc40cc1f84 | |||
a70b197d02 | |||
f50edd40b5 | |||
28f1e430fd | |||
93f5f7bf58 | |||
d20a718320 | |||
7ec41cd447 | |||
334dec8154 | |||
24f07f920f | |||
e6fa2f84a2 | |||
1ee9dae6bf | |||
d28232b9f8 | |||
c83b76ea8f | |||
025ede12e8 | |||
e6c0538d55 | |||
d6b6f634d7 | |||
09abb18be6 | |||
d5e789883f | |||
fa005c6363 | |||
5b78da4689 | |||
1d8923cfbb | |||
4d6e5ddb15 | |||
671422038c | |||
8105c60a4e | |||
ec78c3372c | |||
0584da5cb2 | |||
9ad04deb04 | |||
020b407472 | |||
0254d50128 | |||
2661b4d28c | |||
7c5a832821 | |||
0bb72f29be | |||
ebdac9cc01 | |||
df04b14e2b | |||
b6a4d94ab0 | |||
418791cf79 | |||
ce9337d332 | |||
0b783c01dd | |||
425931a808 | |||
1b94554f1f | |||
924f28e9c4 | |||
6a74971d4b | |||
057873c1b5 | |||
11e58dc484 | |||
f795d2fd15 | |||
2e6732882d | |||
d7d249013f | |||
1f6e7f22ce | |||
edeb936a5d | |||
ac8f1de187 | |||
62e3756904 | |||
1f2ceedec5 | |||
a7d981863f | |||
96b0898f28 | |||
5134eedc45 | |||
269622170e | |||
1db1e1508d | |||
3e8de3af3a | |||
39e972544f | |||
9e3c53c27a | |||
2aada0f308 | |||
1a5ba98964 |
32
.github/workflows/console_cmd_ping__build.yml
vendored
Normal file
32
.github/workflows/console_cmd_ping__build.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: "console_cmd_ping: build-tests"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
|
||||
jobs:
|
||||
build_console_cmd_ping:
|
||||
if: contains(github.event.pull_request.labels.*.name, 'console') || github.event_name == 'push'
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0"]
|
||||
idf_target: ["esp32"]
|
||||
test: [ { app: example, path: "components/console_cmd_ping/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
|
@ -14,7 +14,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0"]
|
||||
test: [ { app: example, path: "examples" }, { app: unit_test, path: "tests/unit_test" }, { app: test_app, path: "tests/test_apps" } ]
|
||||
test: [ { app: example, path: "examples/query_advertise" }, { app: unit_test, path: "tests/unit_test" }, { app: test_app, path: "tests/test_apps" } ]
|
||||
runs-on: ubuntu-20.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
steps:
|
||||
@ -50,7 +50,7 @@ jobs:
|
||||
matrix:
|
||||
idf_ver: ["latest"]
|
||||
idf_target: ["esp32"]
|
||||
test: [ { app: example, path: "examples" }, { app: unit_test, path: "tests/unit_test" }, { app: test_app, path: "tests/test_apps" } ]
|
||||
test: [ { app: example, path: "examples/query_advertise" }, { app: unit_test, path: "tests/unit_test" }, { app: test_app, path: "tests/test_apps" } ]
|
||||
needs: build_mdns
|
||||
runs-on:
|
||||
- self-hosted
|
||||
|
111
.github/workflows/modem__build-host-tests.yml
vendored
111
.github/workflows/modem__build-host-tests.yml
vendored
@ -54,105 +54,12 @@ jobs:
|
||||
|
||||
host_test_esp_modem:
|
||||
if: contains(github.event.pull_request.labels.*.name, 'modem') || github.event_name == 'push'
|
||||
name: Host Tests
|
||||
runs-on: ubuntu-20.04
|
||||
container: espressif/idf:release-v4.3
|
||||
env:
|
||||
lwip: lwip-2.1.2
|
||||
lwip_contrib: contrib-2.1.0
|
||||
lwip_uri: http://download.savannah.nongnu.org/releases/lwip
|
||||
COMP_DIR: esp-protocols/components/esp_modem
|
||||
steps:
|
||||
- name: Checkout esp-protocols
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: esp-protocols
|
||||
|
||||
- name: Build and Test
|
||||
shell: bash
|
||||
run: |
|
||||
apt-get update && apt-get install -y gcc-8 g++-8
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8
|
||||
export LWIP_PATH=`pwd`/${{ env.lwip }}
|
||||
export LWIP_CONTRIB_PATH=`pwd`/${{ env.lwip_contrib }}
|
||||
. ${IDF_PATH}/export.sh
|
||||
$GITHUB_WORKSPACE/${{ env.COMP_DIR }}/test/host_test/env.sh $lwip $lwip_uri $lwip_contrib
|
||||
cd $GITHUB_WORKSPACE/esp-protocols/components/esp_modem/examples/linux_modem
|
||||
idf.py build
|
||||
cd $GITHUB_WORKSPACE/esp-protocols/components/esp_modem/test/host_test
|
||||
idf.py build
|
||||
./build/host_modem_test.elf -r junit -o junit.xml
|
||||
|
||||
- name: Publish Results
|
||||
uses: EnricoMi/publish-unit-test-result-action@v1
|
||||
if: always()
|
||||
with:
|
||||
files: esp-protocols/components/esp_modem/test/host_test/junit.xml
|
||||
|
||||
host_test_gcov_esp_modem:
|
||||
if: contains(github.event.pull_request.labels.*.name, 'modem') || github.event_name == 'push'
|
||||
name: Run gcovr on esp modem host test
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: write
|
||||
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
|
||||
repository: ''
|
||||
persist-credentials: false
|
||||
- name: Build and Test
|
||||
shell: bash
|
||||
run: |
|
||||
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 modem_coverage_report
|
||||
cp $GITHUB_WORKSPACE/${{ env.COMP_DIR }}/index.html modem_coverage_report
|
||||
cp -rf modem_coverage_report $GITHUB_WORKSPACE
|
||||
- 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: modem_coverage_report
|
||||
path: |
|
||||
${{ env.COMP_DIR }}/modem_coverage_report
|
||||
if-no-files-found: error
|
||||
uses: "./.github/workflows/run-host-tests.yml"
|
||||
with:
|
||||
idf_version: "release-v4.3"
|
||||
app_name: "host_modem_test"
|
||||
app_path: "esp-protocols/components/esp_modem/test/host_test"
|
||||
component_path: "esp-protocols/components/esp_modem"
|
||||
upload_artifacts: true
|
||||
pre_run_script: "esp-protocols/components/esp_modem/test/host_test/env.sh"
|
||||
publish_unit_test_result: true
|
||||
|
8
.github/workflows/modem__target-test.yml
vendored
8
.github/workflows/modem__target-test.yml
vendored
@ -16,6 +16,10 @@ jobs:
|
||||
idf_ver: ["latest"]
|
||||
idf_target: ["esp32c3"]
|
||||
test: [ { app: pppd, path: test/target }, { app: sim800_c3, path: examples/pppos_client }, { app: sim800_cmux, path: examples/simple_cmux_client } ]
|
||||
include:
|
||||
- idf_ver: "latest"
|
||||
idf_target: "esp32s2"
|
||||
test: { app: usb_a7670_s2, path: examples/pppos_client }
|
||||
runs-on: ubuntu-20.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
env:
|
||||
@ -55,6 +59,10 @@ jobs:
|
||||
idf_ver: ["latest"]
|
||||
idf_target: ["esp32c3"]
|
||||
test: [ { app: pppd, path: test/target }, { app: sim800_c3, path: examples/pppos_client }, { app: sim800_cmux, path: examples/simple_cmux_client } ]
|
||||
include:
|
||||
- idf_ver: "latest"
|
||||
idf_target: "esp32s2"
|
||||
test: { app: usb_a7670_s2, path: examples/pppos_client }
|
||||
needs: build_esp_modem_tests
|
||||
runs-on:
|
||||
- self-hosted
|
||||
|
@ -27,12 +27,12 @@ jobs:
|
||||
with:
|
||||
workflow: modem__build-host-tests.yml
|
||||
workflow_conclusion: success
|
||||
name: modem_coverage_report
|
||||
path: modem_coverage_report_artifact
|
||||
name: host_modem_test_coverage_report
|
||||
path: host_modem_test_coverage_report_artifact
|
||||
- name: Merge HTML files
|
||||
run: |
|
||||
echo "<html><body>" > index.html
|
||||
cat modem_coverage_report_artifact/index.html >> index.html
|
||||
cat host_modem_test_coverage_report_artifact/index.html >> index.html
|
||||
cat websocket_coverage_report_artifact/index.html >> index.html
|
||||
echo "</body></html>" >> index.html
|
||||
mkdir coverage_report
|
||||
|
1
.github/workflows/publish-docs-component.yml
vendored
1
.github/workflows/publish-docs-component.yml
vendored
@ -94,5 +94,6 @@ jobs:
|
||||
components/esp_websocket_client;
|
||||
components/mdns;
|
||||
components/console_simple_init;
|
||||
components/console_cmd_ping;
|
||||
namespace: "espressif"
|
||||
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}
|
||||
|
31
.github/workflows/run-host-tests.yml
vendored
31
.github/workflows/run-host-tests.yml
vendored
@ -18,12 +18,19 @@ on:
|
||||
upload_artifacts:
|
||||
type: boolean
|
||||
required: true
|
||||
pre_run_script:
|
||||
type: string
|
||||
required: false
|
||||
publish_unit_test_result:
|
||||
type: boolean
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build App
|
||||
runs-on: ubuntu-20.04
|
||||
permissions:
|
||||
checks: write
|
||||
contents: write
|
||||
container: espressif/idf:${{inputs.idf_version}}
|
||||
steps:
|
||||
@ -34,20 +41,35 @@ jobs:
|
||||
- name: Build ${{ inputs.app_name }} with IDF-${{ inputs.idf_version }}
|
||||
shell: bash
|
||||
run: |
|
||||
component=$(basename ${{ inputs.component_path }})
|
||||
if [ -f "${{ inputs.pre_run_script }}" ]; then
|
||||
source ${{ inputs.pre_run_script }} ${{ inputs.idf_version }} $component
|
||||
fi
|
||||
. ${IDF_PATH}/export.sh
|
||||
cd $GITHUB_WORKSPACE/${{inputs.app_path}}
|
||||
cd ${{inputs.app_path}}
|
||||
rm -rf sdkconfig sdkconfig.defaults build
|
||||
# The sdkconfig.ci.linux specifies Linux as the build target with apropriate settings.
|
||||
cp sdkconfig.ci.linux sdkconfig.defaults
|
||||
idf.py build
|
||||
./build/${{inputs.app_name}}.elf
|
||||
./build/${{inputs.app_name}}.elf -r junit -o junit.xml
|
||||
- name: Publish Unit Test Result
|
||||
uses: EnricoMi/publish-unit-test-result-action@v2
|
||||
if: ${{ inputs.publish_unit_test_result }}
|
||||
with:
|
||||
files: ${{inputs.component_path}}/**/*junit.xml
|
||||
- name: Build with Coverage Enabled
|
||||
shell: bash
|
||||
run: |
|
||||
component=$(basename ${{ inputs.component_path }})
|
||||
if [ -f "${{ inputs.pre_run_script }}" ]; then
|
||||
source ${{ inputs.pre_run_script }} ${{ inputs.idf_version }} $component
|
||||
fi
|
||||
. ${IDF_PATH}/export.sh
|
||||
cd $GITHUB_WORKSPACE/${{inputs.app_path}}
|
||||
rm -rf build sdkconfig sdkconfig.defaults
|
||||
cp sdkconfig.ci.coverage sdkconfig.defaults
|
||||
idf.py fullclean
|
||||
# The sdkconfig.ci.coverage specifies Linux as the build target with apropriate settings (CONFIG_GCOV_ENABLED=y).
|
||||
cp sdkconfig.ci.coverage sdkconfig.defaults
|
||||
idf.py build
|
||||
./build/${{inputs.app_name}}.elf
|
||||
- name: Run Coverage
|
||||
@ -56,7 +78,8 @@ jobs:
|
||||
apt-get update && apt-get install -y python3-pip rsync
|
||||
python -m pip install gcovr
|
||||
cd $GITHUB_WORKSPACE/${{inputs.component_path}}
|
||||
gcov `find . -name "*gcda"`
|
||||
component=$(basename ${{ inputs.component_path }})
|
||||
gcov `find . -name "$component*gcda"`
|
||||
gcovr --gcov-ignore-parse-errors -g -k -r . --html index.html -x ${{inputs.app_name}}_coverage.xml
|
||||
mkdir ${{inputs.app_name}}_coverage_report
|
||||
touch ${{inputs.app_name}}_coverage_report/.nojekyll
|
||||
|
@ -2,6 +2,11 @@
|
||||
|
||||
Contributions in the form of pull requests, issue reports, and feature requests are welcome!
|
||||
|
||||
## Common Terminology:
|
||||
* [Type]: Examples include feat (for new features), fix (for bug fixes), ci (for continuous integration), bump (for version updates), etc. You can find a comprehensive list of types in .pre-commit-config.yaml on line 65.
|
||||
* [Scope]: Refers to specific sections or areas within the project, such as mdns, modem, common, console, etc. You can discover additional scopes in .pre-commit-config.yaml on line 65.
|
||||
* [Component]: This is the name of the component, and it should match the directory name where the component code is located.
|
||||
|
||||
## Submitting a PR
|
||||
|
||||
- [ ] Fork the [esp-protocols repository on GitHub](https://github.com/espressif/esp-protocols) to start making your changes.
|
||||
@ -14,6 +19,37 @@ For quick merging, the contribution should be short, and concentrated on a singl
|
||||
|
||||
Please follow the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) rule when writing commit messages.
|
||||
|
||||
A typical commit message title template:
|
||||
|
||||
Template:
|
||||
`[type]([scope]): Message`
|
||||
|
||||
e.g.
|
||||
`feat(console): Added fully operational ifconfig command`
|
||||
|
||||
|
||||
## Creating a new component
|
||||
|
||||
Steps:
|
||||
1. Add a file named .cz.yaml to the root of the component.
|
||||
|
||||
The template for .cz.yaml should look like this:
|
||||
```
|
||||
---
|
||||
commitizen:
|
||||
bump_message: 'bump([scope]): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py [component]
|
||||
tag_format: [component]-v$version
|
||||
version: 0.0.0
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
```
|
||||
2. Run the following command to bump the version of the component:
|
||||
|
||||
`ci/bump [component] [version] --bump-message "bump([scope]): First version [version]"`
|
||||
|
||||
Replace [component], [version] and [scope] with the specific component name, version and scope you are working with. This command will help you bump the version of the component with the provided details.
|
||||
|
||||
## Release process
|
||||
|
||||
When releasing a new component version we have to:
|
||||
|
@ -37,3 +37,7 @@ Please refer to instructions in [ESP-IDF](https://github.com/espressif/esp-idf)
|
||||
### console_simple_init
|
||||
|
||||
* Brief introduction [README](components/console_simple_init/README.md)
|
||||
|
||||
### console_cmd_ping
|
||||
|
||||
* Brief introduction [README](components/console_cmd_ping/README.md)
|
||||
|
2
ci/bump
2
ci/bump
@ -14,7 +14,7 @@ if ! cz bump --dry-run; then
|
||||
fi
|
||||
|
||||
cz_bump_out=`cz bump --files-only "$@"`
|
||||
commit_title=`echo "${cz_bump_out}" | head -1`
|
||||
commit_title=`echo "${cz_bump_out}" | grep "bump(" | head -1`
|
||||
commit_body=`cat ../../release_notes.txt`
|
||||
|
||||
git add -u .
|
||||
|
@ -31,6 +31,11 @@ def main():
|
||||
'breaking': 'Breaking changes',
|
||||
'major': 'Major changes'
|
||||
}
|
||||
|
||||
res = git('show-ref', '--tags', _tty_out=False)
|
||||
if old_ref not in res:
|
||||
old_ref = git('rev-list', '--max-parents=0', 'HEAD', _tty_out=False).strip()
|
||||
|
||||
brief_log = git.log('--oneline', '{}..HEAD'.format(old_ref), '--', 'components/' + component, _tty_out=False)
|
||||
for oneline in brief_log.splitlines():
|
||||
[commit, brief_msg] = oneline.split(' ', 1)
|
||||
@ -80,6 +85,11 @@ def main():
|
||||
changelog += '- {}\n'.format(it)
|
||||
changelog += '\n'
|
||||
filename = os.path.join(root_path, 'components', component, 'CHANGELOG.md')
|
||||
# Check if the changelog file exists.
|
||||
if not os.path.exists(filename):
|
||||
# File does not exist, create it
|
||||
with open(filename, 'w') as file:
|
||||
file.write('# Changelog\n\n')
|
||||
# insert the actual changelog to the beginning of the file, just after the title (2nd line)
|
||||
with open(filename, 'r') as orig_changelog:
|
||||
changelog_title = orig_changelog.readline(
|
||||
|
@ -62,4 +62,3 @@ ignore:
|
||||
- 'components/esp_modem/port/linux/**'
|
||||
- 'components/asio/examples/**'
|
||||
- 'components/mdns/**/esp_system_protocols_linux/**'
|
||||
- 'common_components/protocol_examples_common/**'
|
||||
|
@ -12,6 +12,7 @@ if git log -1 -m --name-only --pretty="" | grep -q components/${comp}/idf_compon
|
||||
echo "${comp}: Component version file has changed"
|
||||
version=`grep version: components/${comp}/.cz.yaml`
|
||||
version=${version#*version: }
|
||||
version="${version//\~/_}"
|
||||
|
||||
tag_format=`grep tag_format: components/${comp}/.cz.yaml`
|
||||
tag_format=${tag_format#*tag_format: }
|
||||
|
@ -1,4 +0,0 @@
|
||||
idf_component_register(SRCS "connect.c" "stdin_out.c" "addr_from_stdin.c"
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_REQUIRES esp_netif driver esp_eth esp_wifi vfs
|
||||
)
|
@ -1,322 +0,0 @@
|
||||
menu "Example Connection Configuration"
|
||||
|
||||
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
|
||||
|
||||
config EXAMPLE_CONNECT_WIFI
|
||||
bool "connect using WiFi interface"
|
||||
default y
|
||||
help
|
||||
Protocol examples can use Wi-Fi and/or Ethernet to connect to the network.
|
||||
Choose this option to connect with WiFi
|
||||
|
||||
if EXAMPLE_CONNECT_WIFI
|
||||
config EXAMPLE_WIFI_SSID
|
||||
string "WiFi SSID"
|
||||
default "myssid"
|
||||
help
|
||||
SSID (network name) for the example to connect to.
|
||||
|
||||
config EXAMPLE_WIFI_PASSWORD
|
||||
string "WiFi Password"
|
||||
default "mypassword"
|
||||
help
|
||||
WiFi password (WPA or WPA2) for the example to use.
|
||||
Can be left blank if the network has no security set.
|
||||
|
||||
choice EXAMPLE_WIFI_SCAN_METHOD
|
||||
prompt "WiFi Scan Method"
|
||||
default EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
|
||||
help
|
||||
WiFi scan method:
|
||||
|
||||
If "Fast" is selected, scan will end after find SSID match AP.
|
||||
|
||||
If "All Channel" is selected, scan will end after scan all the channel.
|
||||
|
||||
config EXAMPLE_WIFI_SCAN_METHOD_FAST
|
||||
bool "Fast"
|
||||
config EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
|
||||
bool "All Channel"
|
||||
endchoice
|
||||
|
||||
menu "WiFi Scan threshold"
|
||||
config EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD
|
||||
int "WiFi minimum rssi"
|
||||
range -127 0
|
||||
|
||||
default -127
|
||||
help
|
||||
The minimum rssi to accept in the scan mode.
|
||||
|
||||
choice EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD
|
||||
prompt "WiFi Scan auth mode threshold"
|
||||
default EXAMPLE_WIFI_AUTH_OPEN
|
||||
help
|
||||
The weakest authmode to accept in the scan mode.
|
||||
|
||||
config EXAMPLE_WIFI_AUTH_OPEN
|
||||
bool "OPEN"
|
||||
config EXAMPLE_WIFI_AUTH_WEP
|
||||
bool "WEP"
|
||||
config EXAMPLE_WIFI_AUTH_WPA_PSK
|
||||
bool "WPA PSK"
|
||||
config EXAMPLE_WIFI_AUTH_WPA2_PSK
|
||||
bool "WPA2 PSK"
|
||||
config EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK
|
||||
bool "WPA WPA2 PSK"
|
||||
config EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE
|
||||
bool "WPA2 ENTERPRISE"
|
||||
config EXAMPLE_WIFI_AUTH_WPA3_PSK
|
||||
bool "WPA3 PSK"
|
||||
config EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK
|
||||
bool "WPA2 WPA3 PSK"
|
||||
config EXAMPLE_WIFI_AUTH_WAPI_PSK
|
||||
bool "WAPI PSK"
|
||||
endchoice
|
||||
endmenu
|
||||
|
||||
choice EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD
|
||||
prompt "WiFi Connect AP Sort Method"
|
||||
default EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
|
||||
help
|
||||
WiFi connect AP sort method:
|
||||
|
||||
If "Signal" is selected, Sort matched APs in scan list by RSSI.
|
||||
|
||||
If "Security" is selected, Sort matched APs in scan list by security mode.
|
||||
|
||||
config EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
|
||||
bool "Signal"
|
||||
config EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY
|
||||
bool "Security"
|
||||
endchoice
|
||||
endif
|
||||
|
||||
config EXAMPLE_CONNECT_ETHERNET
|
||||
bool "connect using Ethernet interface"
|
||||
default n
|
||||
help
|
||||
Protocol examples can use Wi-Fi and/or Ethernet to connect to the network.
|
||||
Choose this option to connect with Ethernet
|
||||
|
||||
if EXAMPLE_CONNECT_ETHERNET
|
||||
config EXAMPLE_USE_SPI_ETHERNET
|
||||
bool
|
||||
|
||||
choice EXAMPLE_ETHERNET_TYPE
|
||||
prompt "Ethernet Type"
|
||||
default EXAMPLE_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32
|
||||
default EXAMPLE_USE_W5500
|
||||
help
|
||||
Select which kind of Ethernet will be used in the example.
|
||||
|
||||
config EXAMPLE_USE_INTERNAL_ETHERNET
|
||||
depends on IDF_TARGET_ESP32
|
||||
select ETH_USE_ESP32_EMAC
|
||||
bool "Internal EMAC"
|
||||
help
|
||||
Select internal Ethernet MAC controller.
|
||||
|
||||
config EXAMPLE_USE_DM9051
|
||||
bool "DM9051 Module"
|
||||
select EXAMPLE_USE_SPI_ETHERNET
|
||||
select ETH_USE_SPI_ETHERNET
|
||||
select ETH_SPI_ETHERNET_DM9051
|
||||
help
|
||||
Select external SPI-Ethernet module.
|
||||
|
||||
config EXAMPLE_USE_W5500
|
||||
bool "W5500 Module"
|
||||
select EXAMPLE_USE_SPI_ETHERNET
|
||||
select ETH_USE_SPI_ETHERNET
|
||||
select ETH_SPI_ETHERNET_W5500
|
||||
help
|
||||
Select external SPI-Ethernet module (W5500).
|
||||
|
||||
config EXAMPLE_USE_OPENETH
|
||||
bool "OpenCores Ethernet MAC (EXPERIMENTAL)"
|
||||
select ETH_USE_OPENETH
|
||||
help
|
||||
When this option is enabled, the example is built with support for
|
||||
OpenCores Ethernet MAC, which allows testing the example in QEMU.
|
||||
Note that this option is used for internal testing purposes, and
|
||||
not officially supported. Examples built with this option enabled
|
||||
will not run on a real ESP32 chip.
|
||||
|
||||
endchoice # EXAMPLE_ETHERNET_TYPE
|
||||
|
||||
if EXAMPLE_USE_INTERNAL_ETHERNET
|
||||
choice EXAMPLE_ETH_PHY_MODEL
|
||||
prompt "Ethernet PHY Device"
|
||||
default EXAMPLE_ETH_PHY_IP101
|
||||
help
|
||||
Select the Ethernet PHY device to use in the example.
|
||||
|
||||
config EXAMPLE_ETH_PHY_IP101
|
||||
bool "IP101"
|
||||
help
|
||||
IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver.
|
||||
Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it.
|
||||
|
||||
config EXAMPLE_ETH_PHY_RTL8201
|
||||
bool "RTL8201/SR8201"
|
||||
help
|
||||
RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
|
||||
Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
|
||||
|
||||
config EXAMPLE_ETH_PHY_LAN87XX
|
||||
bool "LAN87xx"
|
||||
help
|
||||
Below chips are supported:
|
||||
LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
|
||||
flexPWR® Technology.
|
||||
LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
|
||||
LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
|
||||
with HP Auto-MDIX and flexPWR® Technology.
|
||||
LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
|
||||
flexPWR® Technology.
|
||||
Goto https://www.microchip.com for more information about them.
|
||||
|
||||
config EXAMPLE_ETH_PHY_DP83848
|
||||
bool "DP83848"
|
||||
help
|
||||
DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver.
|
||||
Goto http://www.ti.com/product/DP83848J for more information about it.
|
||||
|
||||
config EXAMPLE_ETH_PHY_KSZ80XX
|
||||
bool "KSZ80xx"
|
||||
help
|
||||
With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX
|
||||
Ethernet Physical Layer Tranceivers (PHY).
|
||||
The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041,
|
||||
KSZ8051, KSZ8061, KSZ8081, KSZ8091
|
||||
Goto https://www.microchip.com for more information about them.
|
||||
endchoice
|
||||
|
||||
config EXAMPLE_ETH_MDC_GPIO
|
||||
int "SMI MDC GPIO number"
|
||||
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||
default 23
|
||||
help
|
||||
Set the GPIO number used by SMI MDC.
|
||||
|
||||
config EXAMPLE_ETH_MDIO_GPIO
|
||||
int "SMI MDIO GPIO number"
|
||||
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||
default 18
|
||||
help
|
||||
Set the GPIO number used by SMI MDIO.
|
||||
endif
|
||||
|
||||
if EXAMPLE_USE_SPI_ETHERNET
|
||||
config EXAMPLE_ETH_SPI_HOST
|
||||
int "SPI Host Number"
|
||||
range 0 2
|
||||
default 1
|
||||
help
|
||||
Set the SPI host used to communicate with the SPI Ethernet Controller.
|
||||
|
||||
config EXAMPLE_ETH_SPI_SCLK_GPIO
|
||||
int "SPI SCLK GPIO number"
|
||||
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||
default 14
|
||||
help
|
||||
Set the GPIO number used by SPI SCLK.
|
||||
|
||||
config EXAMPLE_ETH_SPI_MOSI_GPIO
|
||||
int "SPI MOSI GPIO number"
|
||||
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||
default 13
|
||||
help
|
||||
Set the GPIO number used by SPI MOSI.
|
||||
|
||||
config EXAMPLE_ETH_SPI_MISO_GPIO
|
||||
int "SPI MISO GPIO number"
|
||||
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
|
||||
default 12
|
||||
help
|
||||
Set the GPIO number used by SPI MISO.
|
||||
|
||||
config EXAMPLE_ETH_SPI_CS_GPIO
|
||||
int "SPI CS GPIO number"
|
||||
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||
default 15
|
||||
help
|
||||
Set the GPIO number used by SPI CS.
|
||||
|
||||
config EXAMPLE_ETH_SPI_CLOCK_MHZ
|
||||
int "SPI clock speed (MHz)"
|
||||
range 5 80
|
||||
default 36
|
||||
help
|
||||
Set the clock speed (MHz) of SPI interface.
|
||||
|
||||
config EXAMPLE_ETH_SPI_INT_GPIO
|
||||
int "Interrupt GPIO number"
|
||||
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
|
||||
default 4
|
||||
help
|
||||
Set the GPIO number used by the SPI Ethernet module interrupt line.
|
||||
endif # EXAMPLE_USE_SPI_ETHERNET
|
||||
|
||||
config EXAMPLE_ETH_PHY_RST_GPIO
|
||||
int "PHY Reset GPIO number"
|
||||
range -1 ENV_GPIO_OUT_RANGE_MAX
|
||||
default 5
|
||||
help
|
||||
Set the GPIO number used to reset PHY chip.
|
||||
Set to -1 to disable PHY chip hardware reset.
|
||||
|
||||
config EXAMPLE_ETH_PHY_ADDR
|
||||
int "PHY Address"
|
||||
range 0 31 if EXAMPLE_USE_INTERNAL_ETHERNET
|
||||
default 1
|
||||
help
|
||||
Set PHY address according your board schematic.
|
||||
endif # EXAMPLE_CONNECT_ETHERNET
|
||||
|
||||
config EXAMPLE_CONNECT_IPV6
|
||||
bool "Obtain IPv6 address"
|
||||
default y
|
||||
depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET
|
||||
select LWIP_IPV6
|
||||
help
|
||||
By default, examples will wait until IPv4 and IPv6 local link addresses are obtained.
|
||||
Disable this option if the network does not support IPv6.
|
||||
Choose the preferred IPv6 address type if the connection code should wait until other than
|
||||
the local link address gets assigned.
|
||||
Consider enabling IPv6 stateless address autoconfiguration (SLAAC) in the LWIP component.
|
||||
|
||||
if EXAMPLE_CONNECT_IPV6
|
||||
choice EXAMPLE_CONNECT_PREFERRED_IPV6
|
||||
prompt "Preferred IPv6 Type"
|
||||
default EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK
|
||||
help
|
||||
Select which kind of IPv6 address the connect logic waits for.
|
||||
|
||||
config EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK
|
||||
bool "Local Link Address"
|
||||
help
|
||||
Blocks until Local link address assigned.
|
||||
|
||||
config EXAMPLE_CONNECT_IPV6_PREF_GLOBAL
|
||||
bool "Global Address"
|
||||
help
|
||||
Blocks until Global address assigned.
|
||||
|
||||
config EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL
|
||||
bool "Site Local Address"
|
||||
help
|
||||
Blocks until Site link address assigned.
|
||||
|
||||
config EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL
|
||||
bool "Unique Local Link Address"
|
||||
help
|
||||
Blocks until Unique local address assigned.
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
||||
|
||||
endmenu
|
@ -1,68 +0,0 @@
|
||||
#include <string.h>
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "protocol_examples_common.h"
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
#include <lwip/netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define HOST_IP_SIZE 128
|
||||
|
||||
esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *addr_family, struct sockaddr_storage *dest_addr)
|
||||
{
|
||||
char host_ip[HOST_IP_SIZE];
|
||||
int len;
|
||||
static bool already_init = false;
|
||||
|
||||
// this function could be called multiple times -> make sure UART init runs only once
|
||||
if (!already_init) {
|
||||
example_configure_stdin_stdout();
|
||||
already_init = true;
|
||||
}
|
||||
|
||||
// ignore empty or LF only string (could receive from DUT class)
|
||||
do {
|
||||
fgets(host_ip, HOST_IP_SIZE, stdin);
|
||||
len = strlen(host_ip);
|
||||
} while (len <= 1 && host_ip[0] == '\n');
|
||||
host_ip[len - 1] = '\0';
|
||||
|
||||
struct addrinfo hints, *addr_list, *cur;
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
|
||||
// run getaddrinfo() to decide on the IP protocol
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = sock_type;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
if ( getaddrinfo( host_ip, NULL, &hints, &addr_list ) != 0 ) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
for ( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
|
||||
memcpy(dest_addr, cur->ai_addr, sizeof(*dest_addr));
|
||||
if (cur->ai_family == AF_INET) {
|
||||
*ip_protocol = IPPROTO_IP;
|
||||
*addr_family = AF_INET;
|
||||
// add port number and return on first IPv4 match
|
||||
((struct sockaddr_in *)dest_addr)->sin_port = htons(port);
|
||||
freeaddrinfo( addr_list );
|
||||
return ESP_OK;
|
||||
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
else if (cur->ai_family == AF_INET6) {
|
||||
*ip_protocol = IPPROTO_IPV6;
|
||||
*addr_family = AF_INET6;
|
||||
// add port and interface number and return on first IPv6 match
|
||||
((struct sockaddr_in6 *)dest_addr)->sin6_port = htons(port);
|
||||
((struct sockaddr_in6 *)dest_addr)->sin6_scope_id = esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE);
|
||||
freeaddrinfo( addr_list );
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// no match found
|
||||
freeaddrinfo( addr_list );
|
||||
return ESP_FAIL;
|
||||
}
|
@ -1,527 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "protocol_examples_common.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_wifi_default.h"
|
||||
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
#include "esp_eth.h"
|
||||
#if CONFIG_ETH_USE_SPI_ETHERNET
|
||||
#include "driver/spi_master.h"
|
||||
#endif // CONFIG_ETH_USE_SPI_ETHERNET
|
||||
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
#define MAX_IP6_ADDRS_PER_NETIF (5)
|
||||
#define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (s_active_interfaces*2)
|
||||
|
||||
#if defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK)
|
||||
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_LINK_LOCAL
|
||||
#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL)
|
||||
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_GLOBAL
|
||||
#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL)
|
||||
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_SITE_LOCAL
|
||||
#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL)
|
||||
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_UNIQUE_LOCAL
|
||||
#endif // if-elif CONFIG_EXAMPLE_CONNECT_IPV6_PREF_...
|
||||
|
||||
#else
|
||||
#define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (s_active_interfaces)
|
||||
#endif
|
||||
|
||||
#define EXAMPLE_DO_CONNECT CONFIG_EXAMPLE_CONNECT_WIFI || CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
|
||||
#if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST
|
||||
#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN
|
||||
#elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
|
||||
#define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
|
||||
#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
|
||||
#elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY
|
||||
#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_WIFI_AUTH_OPEN
|
||||
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
|
||||
#elif CONFIG_EXAMPLE_WIFI_AUTH_WEP
|
||||
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
|
||||
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK
|
||||
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
|
||||
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK
|
||||
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
|
||||
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK
|
||||
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
|
||||
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE
|
||||
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE
|
||||
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK
|
||||
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
|
||||
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK
|
||||
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
|
||||
#elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK
|
||||
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
|
||||
#endif
|
||||
|
||||
static int s_active_interfaces = 0;
|
||||
static SemaphoreHandle_t s_semph_get_ip_addrs;
|
||||
static esp_netif_t *s_example_esp_netif = NULL;
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
static esp_ip6_addr_t s_ipv6_addr;
|
||||
|
||||
/* types of ipv6 addresses to be displayed on ipv6 events */
|
||||
static const char *s_ipv6_addr_types[] = {
|
||||
"ESP_IP6_ADDR_IS_UNKNOWN",
|
||||
"ESP_IP6_ADDR_IS_GLOBAL",
|
||||
"ESP_IP6_ADDR_IS_LINK_LOCAL",
|
||||
"ESP_IP6_ADDR_IS_SITE_LOCAL",
|
||||
"ESP_IP6_ADDR_IS_UNIQUE_LOCAL",
|
||||
"ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6"
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char *TAG = "example_connect";
|
||||
|
||||
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||
static esp_netif_t *wifi_start(void);
|
||||
static void wifi_stop(void);
|
||||
#endif
|
||||
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
static esp_netif_t *eth_start(void);
|
||||
static void eth_stop(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Checks the netif description if it contains specified prefix.
|
||||
* All netifs created withing common connect component are prefixed with the module TAG,
|
||||
* so it returns true if the specified netif is owned by this module
|
||||
*/
|
||||
static bool is_our_netif(const char *prefix, esp_netif_t *netif)
|
||||
{
|
||||
return strncmp(prefix, esp_netif_get_desc(netif), strlen(prefix) - 1) == 0;
|
||||
}
|
||||
|
||||
/* set up connection, Wi-Fi and/or Ethernet */
|
||||
static void start(void)
|
||||
{
|
||||
|
||||
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||
s_example_esp_netif = wifi_start();
|
||||
s_active_interfaces++;
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
s_example_esp_netif = eth_start();
|
||||
s_active_interfaces++;
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_CONNECT_WIFI && CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
/* if both intefaces at once, clear out to indicate that multiple netifs are active */
|
||||
s_example_esp_netif = NULL;
|
||||
#endif
|
||||
|
||||
#if EXAMPLE_DO_CONNECT
|
||||
/* create semaphore if at least one interface is active */
|
||||
s_semph_get_ip_addrs = xSemaphoreCreateCounting(NR_OF_IP_ADDRESSES_TO_WAIT_FOR, 0);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* tear down connection, release resources */
|
||||
static void stop(void)
|
||||
{
|
||||
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||
wifi_stop();
|
||||
s_active_interfaces--;
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
eth_stop();
|
||||
s_active_interfaces--;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if EXAMPLE_DO_CONNECT
|
||||
static esp_ip4_addr_t s_ip_addr;
|
||||
|
||||
static void on_got_ip(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||
if (!is_our_netif(TAG, event->esp_netif)) {
|
||||
ESP_LOGW(TAG, "Got IPv4 from another interface \"%s\": ignored", esp_netif_get_desc(event->esp_netif));
|
||||
return;
|
||||
}
|
||||
ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
|
||||
memcpy(&s_ip_addr, &event->ip_info.ip, sizeof(s_ip_addr));
|
||||
xSemaphoreGive(s_semph_get_ip_addrs);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
|
||||
static void on_got_ipv6(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
|
||||
if (!is_our_netif(TAG, event->esp_netif)) {
|
||||
ESP_LOGW(TAG, "Got IPv6 from another netif: ignored");
|
||||
return;
|
||||
}
|
||||
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip);
|
||||
ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif),
|
||||
IPV62STR(event->ip6_info.ip), s_ipv6_addr_types[ipv6_type]);
|
||||
if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) {
|
||||
memcpy(&s_ipv6_addr, &event->ip6_info.ip, sizeof(s_ipv6_addr));
|
||||
xSemaphoreGive(s_semph_get_ip_addrs);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
|
||||
esp_err_t example_connect(void)
|
||||
{
|
||||
#if EXAMPLE_DO_CONNECT
|
||||
if (s_semph_get_ip_addrs != NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
#endif
|
||||
start();
|
||||
ESP_ERROR_CHECK(esp_register_shutdown_handler(&stop));
|
||||
ESP_LOGI(TAG, "Waiting for IP(s)");
|
||||
for (int i = 0; i < NR_OF_IP_ADDRESSES_TO_WAIT_FOR; ++i) {
|
||||
xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY);
|
||||
}
|
||||
// iterate over active interfaces, and print out IPs of "our" netifs
|
||||
esp_netif_t *netif = NULL;
|
||||
esp_netif_ip_info_t ip;
|
||||
for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) {
|
||||
netif = esp_netif_next(netif);
|
||||
if (is_our_netif(TAG, netif)) {
|
||||
ESP_LOGI(TAG, "Connected to %s", esp_netif_get_desc(netif));
|
||||
ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip));
|
||||
|
||||
ESP_LOGI(TAG, "- IPv4 address: " IPSTR, IP2STR(&ip.ip));
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
esp_ip6_addr_t ip6[MAX_IP6_ADDRS_PER_NETIF];
|
||||
int ip6_addrs = esp_netif_get_all_ip6(netif, ip6);
|
||||
for (int j = 0; j < ip6_addrs; ++j) {
|
||||
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j]));
|
||||
ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(ip6[j]), s_ipv6_addr_types[ipv6_type]);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t example_disconnect(void)
|
||||
{
|
||||
if (s_semph_get_ip_addrs == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
vSemaphoreDelete(s_semph_get_ip_addrs);
|
||||
s_semph_get_ip_addrs = NULL;
|
||||
stop();
|
||||
ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&stop));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
|
||||
|
||||
static void on_wifi_disconnect(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect...");
|
||||
esp_err_t err = esp_wifi_connect();
|
||||
if (err == ESP_ERR_WIFI_NOT_STARTED) {
|
||||
return;
|
||||
}
|
||||
ESP_ERROR_CHECK(err);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
|
||||
static void on_wifi_connect(void *esp_netif, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
esp_netif_create_ip6_linklocal(esp_netif);
|
||||
}
|
||||
|
||||
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
|
||||
static esp_netif_t *wifi_start(void)
|
||||
{
|
||||
char *desc;
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
|
||||
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA();
|
||||
// Prefix the interface description with the module TAG
|
||||
// Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask)
|
||||
asprintf(&desc, "%s: %s", TAG, esp_netif_config.if_desc);
|
||||
esp_netif_config.if_desc = desc;
|
||||
esp_netif_config.route_prio = 128;
|
||||
esp_netif_t *netif = esp_netif_create_wifi(WIFI_IF_STA, &esp_netif_config);
|
||||
free(desc);
|
||||
esp_wifi_set_default_wifi_sta_handlers();
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, NULL));
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect, netif));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
|
||||
#endif
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
|
||||
wifi_config_t wifi_config = {
|
||||
.sta = {
|
||||
.ssid = CONFIG_EXAMPLE_WIFI_SSID,
|
||||
.password = CONFIG_EXAMPLE_WIFI_PASSWORD,
|
||||
.scan_method = EXAMPLE_WIFI_SCAN_METHOD,
|
||||
.sort_method = EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD,
|
||||
.threshold.rssi = CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD,
|
||||
.threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD,
|
||||
},
|
||||
};
|
||||
ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
esp_wifi_connect();
|
||||
return netif;
|
||||
}
|
||||
|
||||
static void wifi_stop(void)
|
||||
{
|
||||
esp_netif_t *wifi_netif = get_example_netif_from_desc("sta");
|
||||
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect));
|
||||
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip));
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
|
||||
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect));
|
||||
#endif
|
||||
esp_err_t err = esp_wifi_stop();
|
||||
if (err == ESP_ERR_WIFI_NOT_INIT) {
|
||||
return;
|
||||
}
|
||||
ESP_ERROR_CHECK(err);
|
||||
ESP_ERROR_CHECK(esp_wifi_deinit());
|
||||
ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(wifi_netif));
|
||||
esp_netif_destroy(wifi_netif);
|
||||
s_example_esp_netif = NULL;
|
||||
}
|
||||
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
|
||||
/** Event handler for Ethernet events */
|
||||
static void on_eth_event(void *esp_netif, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
switch (event_id) {
|
||||
case ETHERNET_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "Ethernet Link Up");
|
||||
ESP_ERROR_CHECK(esp_netif_create_ip6_linklocal(esp_netif));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
|
||||
static esp_eth_handle_t s_eth_handle = NULL;
|
||||
static esp_eth_mac_t *s_mac = NULL;
|
||||
static esp_eth_phy_t *s_phy = NULL;
|
||||
static esp_eth_netif_glue_handle_t s_eth_glue = NULL;
|
||||
|
||||
static esp_netif_t *eth_start(void)
|
||||
{
|
||||
char *desc;
|
||||
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
|
||||
// Prefix the interface description with the module TAG
|
||||
// Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask)
|
||||
asprintf(&desc, "%s: %s", TAG, esp_netif_config.if_desc);
|
||||
esp_netif_config.if_desc = desc;
|
||||
esp_netif_config.route_prio = 64;
|
||||
esp_netif_config_t netif_config = {
|
||||
.base = &esp_netif_config,
|
||||
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
|
||||
};
|
||||
esp_netif_t *netif = esp_netif_new(&netif_config);
|
||||
assert(netif);
|
||||
free(desc);
|
||||
|
||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||
phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR;
|
||||
phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO;
|
||||
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
|
||||
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||
esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
|
||||
esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
|
||||
s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
|
||||
#if CONFIG_EXAMPLE_ETH_PHY_IP101
|
||||
s_phy = esp_eth_phy_new_ip101(&phy_config);
|
||||
#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
|
||||
s_phy = esp_eth_phy_new_rtl8201(&phy_config);
|
||||
#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
|
||||
s_phy = esp_eth_phy_new_lan87xx(&phy_config);
|
||||
#elif CONFIG_EXAMPLE_ETH_PHY_DP83848
|
||||
s_phy = esp_eth_phy_new_dp83848(&phy_config);
|
||||
#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX
|
||||
s_phy = esp_eth_phy_new_ksz80xx(&phy_config);
|
||||
#endif
|
||||
#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET
|
||||
gpio_install_isr_service(0);
|
||||
#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,
|
||||
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1));
|
||||
#if CONFIG_EXAMPLE_USE_DM9051
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.command_bits = 1,
|
||||
.address_bits = 7,
|
||||
.mode = 0,
|
||||
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
|
||||
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
|
||||
.queue_size = 20
|
||||
};
|
||||
#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);
|
||||
#elif CONFIG_EXAMPLE_USE_W5500
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.command_bits = 16, // Actually it's the address phase in W5500 SPI frame
|
||||
.address_bits = 8, // Actually it's the control phase in W5500 SPI frame
|
||||
.mode = 0,
|
||||
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
|
||||
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
|
||||
.queue_size = 20
|
||||
};
|
||||
#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);
|
||||
#endif
|
||||
#elif CONFIG_EXAMPLE_USE_OPENETH
|
||||
phy_config.autonego_timeout_ms = 100;
|
||||
s_mac = esp_eth_mac_new_openeth(&mac_config);
|
||||
s_phy = esp_eth_phy_new_dp83848(&phy_config);
|
||||
#endif
|
||||
|
||||
// Install Ethernet driver
|
||||
esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy);
|
||||
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle));
|
||||
#if !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
|
||||
/* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually.
|
||||
02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control.
|
||||
*/
|
||||
ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) {
|
||||
0x02, 0x00, 0x00, 0x12, 0x34, 0x56
|
||||
}));
|
||||
#endif
|
||||
// combine driver with netif
|
||||
s_eth_glue = esp_eth_new_netif_glue(s_eth_handle);
|
||||
esp_netif_attach(netif, s_eth_glue);
|
||||
|
||||
// Register user defined event handers
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip, NULL));
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
|
||||
#endif
|
||||
|
||||
esp_eth_start(s_eth_handle);
|
||||
return netif;
|
||||
}
|
||||
|
||||
static void eth_stop(void)
|
||||
{
|
||||
esp_netif_t *eth_netif = get_example_netif_from_desc("eth");
|
||||
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip));
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
|
||||
ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event));
|
||||
#endif
|
||||
ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle));
|
||||
ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue));
|
||||
ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle));
|
||||
s_eth_handle = NULL;
|
||||
ESP_ERROR_CHECK(s_phy->del(s_phy));
|
||||
ESP_ERROR_CHECK(s_mac->del(s_mac));
|
||||
|
||||
esp_netif_destroy(eth_netif);
|
||||
s_example_esp_netif = NULL;
|
||||
}
|
||||
|
||||
esp_eth_handle_t get_example_eth_handle(void)
|
||||
{
|
||||
return s_eth_handle;
|
||||
}
|
||||
|
||||
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
|
||||
esp_netif_t *get_example_netif(void)
|
||||
{
|
||||
return s_example_esp_netif;
|
||||
}
|
||||
|
||||
esp_netif_t *get_example_netif_from_desc(const char *desc)
|
||||
{
|
||||
esp_netif_t *netif = NULL;
|
||||
char *expected_desc;
|
||||
asprintf(&expected_desc, "%s: %s", TAG, desc);
|
||||
while ((netif = esp_netif_next(netif)) != NULL) {
|
||||
if (strcmp(esp_netif_get_desc(netif), expected_desc) == 0) {
|
||||
free(expected_desc);
|
||||
return netif;
|
||||
}
|
||||
}
|
||||
free(expected_desc);
|
||||
return netif;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include <lwip/netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/**
|
||||
* @brief Read and evaluate IP address from stdin
|
||||
*
|
||||
* This API reads stdin and parses the input address using getaddrinfo()
|
||||
* to fill in struct sockaddr_storage (for both IPv4 and IPv6) used to open
|
||||
* a socket. IP protocol is guessed from the IP address string.
|
||||
*
|
||||
* @param[in] port port number of expected connection
|
||||
* @param[in] sock_type expected protocol: SOCK_STREAM or SOCK_DGRAM
|
||||
* @param[out] ip_protocol resultant IP protocol: IPPROTO_IP or IPPROTO_IP6
|
||||
* @param[out] addr_family resultant address family: AF_INET or AF_INET6
|
||||
* @param[out] dest_addr sockaddr_storage structure (for both IPv4 and IPv6)
|
||||
* @return ESP_OK on success, ESP_FAIL otherwise
|
||||
*/
|
||||
esp_err_t get_addr_from_stdin(int port, int sock_type,
|
||||
int *ip_protocol,
|
||||
int *addr_family,
|
||||
struct sockaddr_storage *dest_addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_eth.h"
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
#define EXAMPLE_INTERFACE get_example_netif()
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
|
||||
#define EXAMPLE_INTERFACE get_example_netif()
|
||||
#endif
|
||||
|
||||
#if !defined (CONFIG_EXAMPLE_CONNECT_ETHERNET) && !defined (CONFIG_EXAMPLE_CONNECT_WIFI)
|
||||
// This is useful for some tests which do not need a network connection
|
||||
#define EXAMPLE_INTERFACE NULL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Configure Wi-Fi or Ethernet, connect, wait for IP
|
||||
*
|
||||
* This all-in-one helper function is used in protocols examples to
|
||||
* reduce the amount of boilerplate in the example.
|
||||
*
|
||||
* It is not intended to be used in real world applications.
|
||||
* See examples under examples/wifi/getting_started/ and examples/ethernet/
|
||||
* for more complete Wi-Fi or Ethernet initialization code.
|
||||
*
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*
|
||||
* @return ESP_OK on successful connection
|
||||
*/
|
||||
esp_err_t example_connect(void);
|
||||
|
||||
/**
|
||||
* Counterpart to example_connect, de-initializes Wi-Fi or Ethernet
|
||||
*/
|
||||
esp_err_t example_disconnect(void);
|
||||
|
||||
/**
|
||||
* @brief Configure stdin and stdout to use blocking I/O
|
||||
*
|
||||
* This helper function is used in ASIO examples. It wraps installing the
|
||||
* UART driver and configuring VFS layer to use UART driver for console I/O.
|
||||
*/
|
||||
esp_err_t example_configure_stdin_stdout(void);
|
||||
|
||||
/**
|
||||
* @brief Returns esp-netif pointer created by example_connect()
|
||||
*
|
||||
* @note If multiple interfaces active at once, this API return NULL
|
||||
* In that case the get_example_netif_from_desc() should be used
|
||||
* to get esp-netif pointer based on interface description
|
||||
*/
|
||||
esp_netif_t *get_example_netif(void);
|
||||
|
||||
/**
|
||||
* @brief Returns esp-netif pointer created by example_connect() described by
|
||||
* the supplied desc field
|
||||
*
|
||||
* @param desc Textual interface of created network interface, for example "sta"
|
||||
* indicate default WiFi station, "eth" default Ethernet interface.
|
||||
*
|
||||
*/
|
||||
esp_netif_t *get_example_netif_from_desc(const char *desc);
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
/**
|
||||
* @brief Get the example Ethernet driver handle
|
||||
*
|
||||
* @return esp_eth_handle_t
|
||||
*/
|
||||
esp_eth_handle_t get_example_eth_handle(void);
|
||||
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Common functions for protocol examples, to configure stdin and stdout.
|
||||
*/
|
||||
|
||||
#include "protocol_examples_common.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_vfs_dev.h"
|
||||
#include "driver/uart.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
esp_err_t example_configure_stdin_stdout(void)
|
||||
{
|
||||
// Initialize VFS & UART so we can use std::cout/cin
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
/* Install UART driver for interrupt-driven reads and writes */
|
||||
ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM,
|
||||
256, 0, 0, NULL, 0) );
|
||||
/* Tell VFS to use UART driver */
|
||||
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
|
||||
esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
|
||||
/* Move the caret to the beginning of the next line on '\n' */
|
||||
esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
|
||||
return ESP_OK;
|
||||
}
|
7
components/asio/.cz.yaml
Normal file
7
components/asio/.cz.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
commitizen:
|
||||
bump_message: 'bump(asio): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py asio
|
||||
tag_format: asio-v$version
|
||||
version: 1.28.0~0
|
||||
version_files:
|
||||
- idf_component.yml
|
@ -1,5 +1,40 @@
|
||||
# Changelog
|
||||
|
||||
## [1.28.2~0](https://github.com/espressif/esp-protocols/commits/asio-1.28.2_0)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- reference protocol_examples_common from IDF ([09abb18](https://github.com/espressif/esp-protocols/commit/09abb18))
|
||||
- specify override_path in example manifest files ([1d8923c](https://github.com/espressif/esp-protocols/commit/1d8923c))
|
||||
|
||||
### Updated
|
||||
|
||||
- docs(asio): Updates asio docs ([ce9337d](https://github.com/espressif/esp-protocols/commit/ce9337d))
|
||||
|
||||
## [1.28.0~0](https://github.com/espressif/esp-protocols/commits/asio-1.28.0~0)
|
||||
|
||||
### Features
|
||||
|
||||
- Updates asio to 1.28 ([b310abe](https://github.com/espressif/esp-protocols/commit/b310abe))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Makes the examples to override path ([842b2b2](https://github.com/espressif/esp-protocols/commit/842b2b2))
|
||||
- Removes esp_exception and make all examples to use exceptions ([c1c9350](https://github.com/espressif/esp-protocols/commit/c1c9350))
|
||||
- removed Wno-format flag and fixed formatting warnings ([c48e442](https://github.com/espressif/esp-protocols/commit/c48e442))
|
||||
- added idf_component.yml for examples ([d273e10](https://github.com/espressif/esp-protocols/commit/d273e10))
|
||||
- Reintroduce missing CHANGELOGs ([200cbb3](https://github.com/espressif/esp-protocols/commit/200cbb3), [#235](https://github.com/espressif/esp-protocols/issues/235))
|
||||
|
||||
### Updated
|
||||
|
||||
- docs(common): updated component and example links ([f48d9b2](https://github.com/espressif/esp-protocols/commit/f48d9b2))
|
||||
- docs(common): improving documentation ([ca3fce0](https://github.com/espressif/esp-protocols/commit/ca3fce0))
|
||||
- Add homepage URL and License to all components ([ef3f0ee](https://github.com/espressif/esp-protocols/commit/ef3f0ee))
|
||||
- Added badges with version of components to the respective README files ([e4c8a59](https://github.com/espressif/esp-protocols/commit/e4c8a59))
|
||||
- CI: Fix ASIO example test ([6e2bb51](https://github.com/espressif/esp-protocols/commit/6e2bb51))
|
||||
- Examples: using pytest.ini from top level directory ([aee016d](https://github.com/espressif/esp-protocols/commit/aee016d))
|
||||
- CI: fixing the files to be complient with pre-commit hooks ([945bd17](https://github.com/espressif/esp-protocols/commit/945bd17))
|
||||
|
||||
## [1.14.1~3](https://github.com/espressif/esp-protocols/commits/f148c98)
|
||||
|
||||
### Updated
|
||||
|
40
components/asio/CONTRIBUTING.md
Normal file
40
components/asio/CONTRIBUTING.md
Normal file
@ -0,0 +1,40 @@
|
||||
# Information for Contributors
|
||||
|
||||
Contributions in the form of pull requests, issue reports, and feature requests are welcome!
|
||||
|
||||
## Updating ASIO
|
||||
|
||||
ASIO is managed as a submodule, to updated the version first the [espressif](github.com/espressif/asio) ASIO fork must be updated.
|
||||
|
||||
## Release process
|
||||
|
||||
When releasing a new component version we have to:
|
||||
|
||||
* Update the submodule reference
|
||||
* Update the version number
|
||||
* Update the changelog
|
||||
|
||||
And the automation process takes care of the last steps:
|
||||
|
||||
* Create the version tag in this repository
|
||||
* Deploy the component to component registry
|
||||
* Update the documentation
|
||||
|
||||
This process needs to be manually handled for ASIO component since commitizen doesn't accept the versioning schema used.
|
||||
|
||||
* Increment manually the version in the [manifest file](idf_component.yml)
|
||||
* Export environment variables for changelog generation:
|
||||
- CZ_PRE_CURRENT_TAG_VERSION
|
||||
- CZ_PRE_NEW_TAG_VERSION
|
||||
- CZ_PRE_NEW_VERSION
|
||||
* Run `python ../../ci/changelog.py asio` from this directory to generate the change log
|
||||
* Check the updated `CHANGELOG.md`
|
||||
* Commit the changes with the adequated message format.
|
||||
```
|
||||
bump(asio): $current_version -> $new_version
|
||||
|
||||
$Changelog for the version
|
||||
```
|
||||
* Create a PR
|
||||
|
||||
Once the PR is merged, the CI job tags the merge commit, creates a new release, builds and deploys documentation and the new component to the component registry
|
Submodule components/asio/asio updated: 9cf116aa63...a2e0f70d61
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# (Not part of the boilerplate)
|
||||
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
|
||||
set(EXTRA_COMPONENT_DIRS ../.. ../../../../common_components/protocol_examples_common)
|
||||
set(EXTRA_COMPONENT_DIRS ../.. $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(asio_chat)
|
||||
|
@ -3,4 +3,4 @@ dependencies:
|
||||
idf: ">=5.0"
|
||||
espressif/asio:
|
||||
version: "^1.14.1"
|
||||
override_path: '../../../'
|
||||
override_path: "../../../"
|
||||
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# (Not part of the boilerplate)
|
||||
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
|
||||
set(EXTRA_COMPONENT_DIRS ../../ ../../../../common_components/protocol_examples_common)
|
||||
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(async_http_request)
|
||||
|
@ -25,6 +25,7 @@ The control of lifetime of the class, done by `std::shared_ptr` usage, guarantee
|
||||
async operations until it's not needed any more. This makes necessary that all of the async operation class must start
|
||||
its lifetime as a `std::shared_ptr` due to the usage of `std::enable_shared_from_this`.
|
||||
|
||||
```
|
||||
|
||||
User creates a shared_ptr──┐
|
||||
of AddressResolution and │
|
||||
@ -47,6 +48,7 @@ its lifetime as a `std::shared_ptr` due to the usage of `std::enable_shared_from
|
||||
is called. │
|
||||
└────►Completion Handler()
|
||||
|
||||
```
|
||||
|
||||
The previous diagram shows the process and the life span of each of the tasks in this examples. At each stage the
|
||||
object responsible for the last action inject itself to the completion handler of the next stage for reuse.
|
||||
|
@ -3,4 +3,4 @@ dependencies:
|
||||
idf: ">=5.0"
|
||||
espressif/asio:
|
||||
version: "^1.14.1"
|
||||
override_path: '../../../'
|
||||
override_path: "../../../"
|
||||
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# (Not part of the boilerplate)
|
||||
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
|
||||
set(EXTRA_COMPONENT_DIRS ../.. ../../../../common_components/protocol_examples_common)
|
||||
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(asio_sock4)
|
||||
|
@ -3,4 +3,4 @@ dependencies:
|
||||
idf: ">=5.0"
|
||||
espressif/asio:
|
||||
version: "^1.14.1"
|
||||
override_path: '../../../'
|
||||
override_path: "../../../"
|
||||
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# (Not part of the boilerplate)
|
||||
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
|
||||
set(EXTRA_COMPONENT_DIRS ../.. ../../../../common_components/protocol_examples_common)
|
||||
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
|
||||
set(EXCLUDE_COMPONENTS openssl)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
@ -3,4 +3,4 @@ dependencies:
|
||||
idf: ">=5.0"
|
||||
espressif/asio:
|
||||
version: "^1.14.1"
|
||||
override_path: '../../../'
|
||||
override_path: "../../../"
|
||||
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# (Not part of the boilerplate)
|
||||
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
|
||||
set(EXTRA_COMPONENT_DIRS ../.. ../../../../common_components/protocol_examples_common)
|
||||
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(asio_tcp_echo_server)
|
||||
|
@ -3,4 +3,4 @@ dependencies:
|
||||
idf: ">=5.0"
|
||||
espressif/asio:
|
||||
version: "^1.14.1"
|
||||
override_path: '../../../'
|
||||
override_path: "../../../"
|
||||
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# (Not part of the boilerplate)
|
||||
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
|
||||
set(EXTRA_COMPONENT_DIRS ../../ ../../../../common_components/protocol_examples_common)
|
||||
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(asio_udp_echo_server)
|
||||
|
@ -3,4 +3,4 @@ dependencies:
|
||||
idf: ">=5.0"
|
||||
espressif/asio:
|
||||
version: "^1.14.1"
|
||||
override_path: '../../../'
|
||||
override_path: "../../../"
|
||||
|
@ -1,6 +1,9 @@
|
||||
version: "1.14.1~3"
|
||||
description: ASIO
|
||||
version: "1.28.2~0"
|
||||
description: Cross-platform C++ library for network and I/O programming
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/asio
|
||||
issues: https://github.com/espressif/esp-protocols/issues
|
||||
documentation: https://docs.espressif.com/projects/esp-protocols/asio/docs/latest/index.html
|
||||
repository: https://github.com/espressif/esp-protocols.git
|
||||
dependencies:
|
||||
idf:
|
||||
version: ">=5.0"
|
||||
|
8
components/console_cmd_ping/.cz.yaml
Normal file
8
components/console_cmd_ping/.cz.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
commitizen:
|
||||
bump_message: 'bump(console): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py console_cmd_ping
|
||||
tag_format: console_cmd_ping-v$version
|
||||
version: 0.0.9
|
||||
version_files:
|
||||
- idf_component.yml
|
4
components/console_cmd_ping/CMakeLists.txt
Normal file
4
components/console_cmd_ping/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
idf_component_register(SRCS "console_ping.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES esp_netif console
|
||||
WHOLE_ARCHIVE)
|
201
components/console_cmd_ping/LICENSE
Normal file
201
components/console_cmd_ping/LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
55
components/console_cmd_ping/README.md
Normal file
55
components/console_cmd_ping/README.md
Normal file
@ -0,0 +1,55 @@
|
||||
# Console command ping
|
||||
The component provides a console where the 'ping' command can be executed.
|
||||
|
||||
## API
|
||||
|
||||
### Steps to enable console in an example code:
|
||||
1. Add this component to your project using ```idf.py add-dependency``` command.
|
||||
2. In the main file of the example, add the following line:
|
||||
```c
|
||||
#include "console_ping.h"
|
||||
```
|
||||
3. Ensure esp-netif and NVS flash is initialized and default event loop is created in your app_main():
|
||||
```c
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
esp_err_t ret = nvs_flash_init(); //Initialize NVS
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(ret);
|
||||
```
|
||||
4. In your app_main() function, add the following line as the last line:
|
||||
```c
|
||||
ESP_ERROR_CHECK(console_cmd_init()); // Initialize console
|
||||
|
||||
// Register all plugin command added to your project
|
||||
ESP_ERROR_CHECK(console_cmd_all_register());
|
||||
|
||||
// To register only ifconfig command skip calling console_cmd_all_register()
|
||||
ESP_ERROR_CHECK(console_cmd_ping_register());
|
||||
|
||||
ESP_ERROR_CHECK(console_cmd_start()); // Start console
|
||||
```
|
||||
|
||||
### Adding a plugin command or component:
|
||||
To add a plugin command or any component from IDF component manager into your project, simply include an entry within the `idf_component.yml` file.
|
||||
|
||||
For more details refer [IDF Component Manager](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html)
|
||||
|
||||
|
||||
## Suported command:
|
||||
|
||||
### ping:
|
||||
```
|
||||
ping [-W <t>] [-i <t>] [-s <n>] [-c <n>] [-Q <n>] [-T <n>] <host>
|
||||
send ICMP ECHO_REQUEST to network hosts
|
||||
-W, --timeout=<t> Time to wait for a response, in seconds
|
||||
-i, --interval=<t> Wait interval seconds between sending each packet
|
||||
-s, --size=<n> Specify the number of data bytes to be sent
|
||||
-c, --count=<n> Stop after sending count packets
|
||||
-Q, --tos=<n> Set Type of Service related bits in IP datagrams
|
||||
-T, --ttl=<n> Set Time to Live related bits in IP datagrams
|
||||
<host> Host address
|
||||
```
|
215
components/console_cmd_ping/console_ping.c
Normal file
215
components/console_cmd_ping/console_ping.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "esp_console.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
#include "ping/ping_sock.h"
|
||||
#include "console_ping.h"
|
||||
|
||||
|
||||
static const char *TAG = "console_ping";
|
||||
SemaphoreHandle_t sync_semaphore;
|
||||
|
||||
|
||||
/**
|
||||
* Static registration of this plugin is achieved by defining the plugin description
|
||||
* structure and placing it into .console_cmd_desc section.
|
||||
* The name of the section and its placement is determined by linker.lf file in 'plugins' component.
|
||||
*/
|
||||
static const console_cmd_plugin_desc_t __attribute__((section(".console_cmd_desc"), used)) PLUGIN = {
|
||||
.name = "console_cmd_ping",
|
||||
.plugin_regd_fn = &console_cmd_ping_register
|
||||
};
|
||||
|
||||
|
||||
static void cmd_ping_on_ping_success(esp_ping_handle_t hdl, void *args)
|
||||
{
|
||||
uint8_t ttl;
|
||||
uint16_t seqno;
|
||||
uint32_t elapsed_time, recv_len;
|
||||
ip_addr_t target_addr;
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_TTL, &ttl, sizeof(ttl));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time));
|
||||
printf("%" PRIu32 " bytes from %s icmp_seq=%" PRIu16 " ttl=%" PRIu16 " time=%" PRIu32 " ms\n",
|
||||
recv_len, ipaddr_ntoa((ip_addr_t *)&target_addr), seqno, ttl, elapsed_time);
|
||||
}
|
||||
|
||||
static void cmd_ping_on_ping_timeout(esp_ping_handle_t hdl, void *args)
|
||||
{
|
||||
uint16_t seqno;
|
||||
ip_addr_t target_addr;
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
|
||||
printf("From %s icmp_seq=%d timeout\n", ipaddr_ntoa((ip_addr_t *)&target_addr), seqno);
|
||||
}
|
||||
|
||||
static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args)
|
||||
{
|
||||
ip_addr_t target_addr;
|
||||
uint32_t transmitted;
|
||||
uint32_t received;
|
||||
uint32_t total_time_ms;
|
||||
uint32_t loss;
|
||||
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_REQUEST, &transmitted, sizeof(transmitted));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_REPLY, &received, sizeof(received));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
|
||||
esp_ping_get_profile(hdl, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms));
|
||||
|
||||
if (transmitted > 0) {
|
||||
loss = (uint32_t)((1 - ((float)received) / transmitted) * 100);
|
||||
} else {
|
||||
loss = 0;
|
||||
}
|
||||
if (IP_IS_V4(&target_addr)) {
|
||||
printf("\n--- %s ping statistics ---\n", inet_ntoa(*ip_2_ip4(&target_addr)));
|
||||
} else {
|
||||
printf("\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&target_addr)));
|
||||
}
|
||||
printf("%" PRIu32 " packets transmitted, %" PRIu32 " received, %" PRIu32 "%% packet loss, time %" PRIu32 "ms\n",
|
||||
transmitted, received, loss, total_time_ms);
|
||||
// delete the ping sessions, so that we clean up all resources and can create a new ping session
|
||||
ESP_ERROR_CHECK(esp_ping_delete_session(hdl));
|
||||
|
||||
/* Give the semaphore as ping task is done */
|
||||
xSemaphoreGive(sync_semaphore);
|
||||
}
|
||||
|
||||
static struct {
|
||||
struct arg_dbl *timeout;
|
||||
struct arg_dbl *interval;
|
||||
struct arg_int *data_size;
|
||||
struct arg_int *count;
|
||||
struct arg_int *tos;
|
||||
struct arg_int *ttl;
|
||||
struct arg_str *host;
|
||||
struct arg_end *end;
|
||||
} ping_args;
|
||||
|
||||
static int do_ping_cmd(int argc, char **argv)
|
||||
{
|
||||
esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG();
|
||||
|
||||
int nerrors = arg_parse(argc, argv, (void **)&ping_args);
|
||||
if (nerrors != 0) {
|
||||
arg_print_errors(stderr, ping_args.end, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ping_args.timeout->count > 0) {
|
||||
config.timeout_ms = (uint32_t)(ping_args.timeout->dval[0] * 1000);
|
||||
}
|
||||
|
||||
if (ping_args.interval->count > 0) {
|
||||
config.interval_ms = (uint32_t)(ping_args.interval->dval[0] * 1000);
|
||||
}
|
||||
|
||||
if (ping_args.data_size->count > 0) {
|
||||
config.data_size = (uint32_t)(ping_args.data_size->ival[0]);
|
||||
}
|
||||
|
||||
if (ping_args.count->count > 0) {
|
||||
config.count = (uint32_t)(ping_args.count->ival[0]);
|
||||
}
|
||||
|
||||
if (ping_args.tos->count > 0) {
|
||||
config.tos = (uint32_t)(ping_args.tos->ival[0]);
|
||||
}
|
||||
|
||||
if (ping_args.ttl->count > 0) {
|
||||
config.ttl = (uint32_t)(ping_args.ttl->ival[0]);
|
||||
}
|
||||
|
||||
// parse IP address
|
||||
struct sockaddr_in6 sock_addr6;
|
||||
ip_addr_t target_addr = {0};
|
||||
|
||||
if (inet_pton(AF_INET6, ping_args.host->sval[0], &sock_addr6.sin6_addr) == 1) {
|
||||
/* convert ip6 string to ip6 address */
|
||||
ipaddr_aton(ping_args.host->sval[0], &target_addr);
|
||||
} else {
|
||||
struct addrinfo hint = {0};
|
||||
struct addrinfo *res = NULL;
|
||||
|
||||
/* convert ip4 string or hostname to ip4 or ip6 address */
|
||||
if (getaddrinfo(ping_args.host->sval[0], NULL, &hint, &res) != 0) {
|
||||
printf("ping: unknown host %s\n", ping_args.host->sval[0]);
|
||||
return 1;
|
||||
}
|
||||
if (res->ai_family == AF_INET) {
|
||||
struct in_addr addr4 = ((struct sockaddr_in *) (res->ai_addr))->sin_addr;
|
||||
inet_addr_to_ip4addr(ip_2_ip4(&target_addr), &addr4);
|
||||
} else {
|
||||
struct in6_addr addr6 = ((struct sockaddr_in6 *) (res->ai_addr))->sin6_addr;
|
||||
inet6_addr_to_ip6addr(ip_2_ip6(&target_addr), &addr6);
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
config.target_addr = target_addr;
|
||||
|
||||
/* set callback functions */
|
||||
esp_ping_callbacks_t cbs = {
|
||||
.cb_args = NULL,
|
||||
.on_ping_success = cmd_ping_on_ping_success,
|
||||
.on_ping_timeout = cmd_ping_on_ping_timeout,
|
||||
.on_ping_end = cmd_ping_on_ping_end
|
||||
};
|
||||
esp_ping_handle_t ping;
|
||||
ESP_ERROR_CHECK(esp_ping_new_session(&config, &cbs, &ping));
|
||||
ESP_ERROR_CHECK(esp_ping_start(ping));
|
||||
|
||||
/* Wait till the ping task is done */
|
||||
if (xSemaphoreTake(sync_semaphore, portMAX_DELAY) != pdTRUE) {
|
||||
ESP_LOGE(TAG, "Error in xSemaphoreTake\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Registers the ping command.
|
||||
*
|
||||
* @return
|
||||
* - esp_err_t
|
||||
*/
|
||||
esp_err_t console_cmd_ping_register(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
sync_semaphore = xSemaphoreCreateBinary();
|
||||
|
||||
ping_args.timeout = arg_dbl0("W", "timeout", "<t>", "Time to wait for a response, in seconds");
|
||||
ping_args.interval = arg_dbl0("i", "interval", "<t>", "Wait interval seconds between sending each packet");
|
||||
ping_args.data_size = arg_int0("s", "size", "<n>", "Specify the number of data bytes to be sent");
|
||||
ping_args.count = arg_int0("c", "count", "<n>", "Stop after sending count packets");
|
||||
ping_args.tos = arg_int0("Q", "tos", "<n>", "Set Type of Service related bits in IP datagrams");
|
||||
ping_args.ttl = arg_int0("T", "ttl", "<n>", "Set Time to Live related bits in IP datagrams");
|
||||
ping_args.host = arg_str1(NULL, NULL, "<host>", "Host address");
|
||||
ping_args.end = arg_end(1);
|
||||
const esp_console_cmd_t ping_cmd = {
|
||||
.command = "ping",
|
||||
.help = "send ICMP ECHO_REQUEST to network hosts",
|
||||
.hint = NULL,
|
||||
.func = &do_ping_cmd,
|
||||
.argtable = &ping_args
|
||||
};
|
||||
|
||||
ret = esp_console_cmd_register(&ping_cmd);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "Unable to register ping");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
25
components/console_cmd_ping/console_ping.h
Normal file
25
components/console_cmd_ping/console_ping.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "console_simple_init.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Registers the ping command.
|
||||
*
|
||||
* @return
|
||||
* - esp_err_t
|
||||
*/
|
||||
esp_err_t console_cmd_ping_register(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
# 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)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(ping-basic)
|
@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "ping-basic.c"
|
||||
INCLUDE_DIRS ".")
|
@ -0,0 +1,6 @@
|
||||
dependencies:
|
||||
idf:
|
||||
version: ">=5.0"
|
||||
console_cmd_ping:
|
||||
version: "*"
|
||||
override_path: '../../../'
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "esp_netif.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_event.h"
|
||||
#include "console_ping.h"
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
esp_err_t ret = nvs_flash_init(); //Initialize NVS
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
// Initialize console REPL
|
||||
ESP_ERROR_CHECK(console_cmd_init());
|
||||
|
||||
// Register ping command
|
||||
ESP_ERROR_CHECK(console_cmd_ping_register());
|
||||
|
||||
// start console REPL
|
||||
ESP_ERROR_CHECK(console_cmd_start());
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
def test_examples_ping_command(dut):
|
||||
dut.expect('esp>', timeout=30)
|
||||
dut.write('ping 127.0.0.1')
|
||||
dut.expect('5 packets transmitted, 5 received, 0% packet loss, time 0ms', timeout=30)
|
||||
pass
|
10
components/console_cmd_ping/idf_component.yml
Normal file
10
components/console_cmd_ping/idf_component.yml
Normal file
@ -0,0 +1,10 @@
|
||||
version: 0.0.9
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/console_cmd_ping
|
||||
description: The component provides a console where the 'ping' command can be executed.
|
||||
dependencies:
|
||||
idf:
|
||||
version: '>=5.0'
|
||||
espressif/console_simple_init:
|
||||
version: '>=1.1.0'
|
||||
override_path: '../console_simple_init'
|
||||
public: true
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(console): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py console_simple_init
|
||||
tag_format: console_simple_init-v$version
|
||||
version: 1.0.2
|
||||
version: 1.1.0
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## [1.1.0](https://github.com/espressif/esp-protocols/commits/console_simple_init-v1.1.0)
|
||||
|
||||
### Features
|
||||
|
||||
- Added runtime component registration support in console_simple_init ([057873c1](https://github.com/espressif/esp-protocols/commit/057873c1))
|
||||
|
||||
## [1.0.2](https://github.com/espressif/esp-protocols/commits/console_simple_init-v1.0.2)
|
||||
|
||||
### Bug Fixes
|
||||
|
@ -1,3 +1,4 @@
|
||||
idf_component_register(SRCS "console_simple_init.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES console)
|
||||
PRIV_REQUIRES console
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
@ -32,6 +32,28 @@ It also provides an api to register an user provided command.
|
||||
// This allows you to execute the do_user_cmd function when the "user" command is invoked
|
||||
ESP_ERROR_CHECK(console_cmd_user_register("user", do_user_cmd));
|
||||
|
||||
// Register any other plugin command added to your project
|
||||
ESP_ERROR_CHECK(console_cmd_all_register());
|
||||
|
||||
ESP_ERROR_CHECK(console_cmd_start()); // Start console
|
||||
```
|
||||
|
||||
### Automatic registration of console commands
|
||||
The `console_simple_init` component includes a utility function named `console_cmd_all_register()`. This function automates the registration of all commands that are linked into the application. To use this functionality, the application can call `console_cmd_all_register()` as demonstrated above.
|
||||
|
||||
When creating a new component, you can ensure that its commands are registered automatically by placing the registration function into the `.console_cmd_desc` section within the output binary.
|
||||
|
||||
To achieve this, follow these steps:
|
||||
1. Add the following lines to the main file of the component
|
||||
```
|
||||
static const console_cmd_plugin_desc_t __attribute__((section(".console_cmd_desc"), used)) PLUGIN = {
|
||||
.name = "cmd_name_string",
|
||||
.plugin_regd_fn = &cmd_registration_function
|
||||
};̌
|
||||
```
|
||||
2. Add the `WHOLE_ARCHIVE` flag to CMakeLists.txt of the component.
|
||||
|
||||
|
||||
For more details refer:
|
||||
* [IDF Component Manager](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html)
|
||||
* [Linker Script Generation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/linker-script-generation.html)
|
||||
|
@ -8,13 +8,13 @@
|
||||
#include "esp_log.h"
|
||||
#include "console_simple_init.h"
|
||||
|
||||
|
||||
static esp_console_repl_t *repl = NULL;
|
||||
static const char *TAG = "console_simple_init";
|
||||
|
||||
/**
|
||||
* @brief Initializes the esp console
|
||||
* @return
|
||||
* - esp_err_t
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t console_cmd_init(void)
|
||||
{
|
||||
@ -40,13 +40,12 @@ esp_err_t console_cmd_init(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize Ethernet driver based on Espressif IoT Development Framework Configuration
|
||||
* @brief Register a user supplied command
|
||||
*
|
||||
* @param[in] cmd string that is the user defined command
|
||||
* @param[in] do_user_cmd Function pointer for a user-defined command callback function
|
||||
*
|
||||
* @return
|
||||
* - esp_err_t
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t console_cmd_user_register(char *cmd, esp_console_cmd_func_t do_user_cmd)
|
||||
{
|
||||
@ -67,10 +66,36 @@ esp_err_t console_cmd_user_register(char *cmd, esp_console_cmd_func_t do_user_cm
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register all the console commands in .console_cmd_desc section
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t console_cmd_all_register(void)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
extern const console_cmd_plugin_desc_t _console_cmd_array_start;
|
||||
extern const console_cmd_plugin_desc_t _console_cmd_array_end;
|
||||
|
||||
ESP_LOGI(TAG, "List of Console commands:\n");
|
||||
for (const console_cmd_plugin_desc_t *it = &_console_cmd_array_start; it != &_console_cmd_array_end; ++it) {
|
||||
ESP_LOGI(TAG, "- Command '%s', function plugin_regd_fn=%p\n", it->name, it->plugin_regd_fn);
|
||||
if (it->plugin_regd_fn != NULL) {
|
||||
ret = (it->plugin_regd_fn)();
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Starts the esp console
|
||||
* @return
|
||||
* - esp_err_t
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t console_cmd_start(void)
|
||||
{
|
||||
|
@ -13,28 +13,46 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* This stucture describes the plugin to the rest of the application */
|
||||
typedef struct {
|
||||
/* A pointer to the name of the command */
|
||||
const char *name;
|
||||
|
||||
/* A function which performs auto-registration of console commands */
|
||||
esp_err_t (*plugin_regd_fn)(void);
|
||||
} console_cmd_plugin_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializes the esp console
|
||||
* @return
|
||||
* - esp_err_t
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t console_cmd_init(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize Ethernet driver based on Espressif IoT Development Framework Configuration
|
||||
* @brief Register a user supplied command
|
||||
*
|
||||
* @param[in] cmd string that is the user defined command
|
||||
* @param[in] do_user_cmd Function pointer for a user-defined command callback function
|
||||
*
|
||||
* @return
|
||||
* - esp_err_t
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t console_cmd_user_register(char *user_cmd, esp_console_cmd_func_t do_user_cmd);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register all the console commands in .console_cmd_desc section
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t console_cmd_all_register(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Starts the esp console
|
||||
* @return
|
||||
* - esp_err_t
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t console_cmd_start(void);
|
||||
|
||||
|
@ -30,6 +30,9 @@ void app_main(void)
|
||||
// Register user command
|
||||
ESP_ERROR_CHECK(console_cmd_user_register("user", do_user_cmd));
|
||||
|
||||
// Register all the plugin commands added to this example
|
||||
ESP_ERROR_CHECK(console_cmd_all_register());
|
||||
|
||||
// start console REPL
|
||||
ESP_ERROR_CHECK(console_cmd_start());
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
dependencies:
|
||||
idf:
|
||||
version: '*'
|
||||
version: ">=5.0"
|
||||
console_simple_init:
|
||||
version: "*"
|
||||
override_path: '../../../'
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 1.0.2
|
||||
version: 1.1.0
|
||||
description: The component provides helper functions for easy initialization and start of esp console.
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/console_simple_init
|
||||
dependencies:
|
||||
|
13
components/console_simple_init/linker.lf
Normal file
13
components/console_simple_init/linker.lf
Normal file
@ -0,0 +1,13 @@
|
||||
[sections:console_cmd_desc]
|
||||
entries:
|
||||
.console_cmd_desc
|
||||
|
||||
[scheme:console_cmd_desc_default]
|
||||
entries:
|
||||
console_cmd_desc -> flash_rodata
|
||||
|
||||
[mapping:console_cmd_desc]
|
||||
archive: *
|
||||
entries:
|
||||
* (console_cmd_desc_default);
|
||||
console_cmd_desc -> flash_rodata KEEP() SORT(name) SURROUND(console_cmd_array)
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(modem): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py esp_modem
|
||||
tag_format: modem-v$version
|
||||
version: 1.0.3
|
||||
version: 1.0.4
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## [1.0.4](https://github.com/espressif/esp-protocols/commits/modem-v1.0.4)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Added USB runner with ESP32S2 with A7670 ([edeb936](https://github.com/espressif/esp-protocols/commit/edeb936))
|
||||
- Extend docs on AT client example ([1f2ceed](https://github.com/espressif/esp-protocols/commit/1f2ceed))
|
||||
- Fix pytest exclusion, gitignore, and changelog checks ([2696221](https://github.com/espressif/esp-protocols/commit/2696221))
|
||||
- Fix DTE to post fragments to parsers for USB term ([1db1e15](https://github.com/espressif/esp-protocols/commit/1db1e15))
|
||||
- Fix DUAL_MODE regression from cb6e03ac ([2aada0f](https://github.com/espressif/esp-protocols/commit/2aada0f))
|
||||
- Fix AT client example to use custom AT processing ([1a5ba98](https://github.com/espressif/esp-protocols/commit/1a5ba98), [#352](https://github.com/espressif/esp-protocols/issues/352))
|
||||
|
||||
## [1.0.3](https://github.com/espressif/esp-protocols/commits/modem-v1.0.3)
|
||||
|
||||
### Bug Fixes
|
||||
|
@ -42,6 +42,9 @@ set_target_properties(${COMPONENT_LIB} PROPERTIES
|
||||
CXX_EXTENSIONS ON
|
||||
)
|
||||
|
||||
if(CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE)
|
||||
idf_component_optional_requires(PUBLIC main)
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "linux")
|
||||
# This is needed for ESP_LOGx() macros, as integer formats differ on ESP32(..) and x64
|
||||
|
@ -45,4 +45,22 @@ menu "esp-modem"
|
||||
to make the protocol more robust on noisy environments or when underlying
|
||||
transport gets corrupted often (for example by Rx buffer overflows)
|
||||
|
||||
config ESP_MODEM_ADD_CUSTOM_MODULE
|
||||
bool "Add support for custom module in C-API"
|
||||
default n
|
||||
help
|
||||
If enabled, we adapt the C-API to create a DCE from a user defined class
|
||||
|
||||
config ESP_MODEM_CUSTOM_MODULE_HEADER
|
||||
string "Header file name which defines custom DCE creation"
|
||||
depends on ESP_MODEM_ADD_CUSTOM_MODULE
|
||||
default "custom_module.hpp"
|
||||
help
|
||||
Name of the header file in the main component which implements esp_modem_create_custom_dce()
|
||||
called from C-API for creating esp_modem_dce object.
|
||||
This header provides definition of the custom module with some additional and/or updated commands
|
||||
and API. It also defines creation of DCE based on this custom module, typically calling:
|
||||
dce_factory::Factory::create_unique_dce_from<CustomModule, DCE*>(dce_config, std::move(dte), netif)
|
||||
Please refer to the pppos_client example for more details.
|
||||
|
||||
endmenu
|
||||
|
@ -2,7 +2,5 @@
|
||||
# CMakeLists 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/project.cmake)
|
||||
project(ap-to-pppos)
|
||||
|
@ -0,0 +1,4 @@
|
||||
dependencies:
|
||||
espressif/esp_modem:
|
||||
version: "^1.0.1"
|
||||
override_path: "../../../"
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../.. ../../port/linux)
|
||||
set(EXTRA_COMPONENT_DIRS ../../port/linux)
|
||||
|
||||
set(COMPONENTS main)
|
||||
project(linux_modem)
|
||||
|
@ -0,0 +1,4 @@
|
||||
dependencies:
|
||||
espressif/esp_modem:
|
||||
version: "^1.0.1"
|
||||
override_path: "../../../"
|
@ -0,0 +1,5 @@
|
||||
CONFIG_IDF_TARGET="linux"
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||||
CONFIG_COMPILER_CXX_RTTI=y
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0
|
||||
CONFIG_COMPILER_STACK_CHECK_NONE=y
|
@ -1,10 +0,0 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := modem-console
|
||||
|
||||
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
@ -1,4 +0,0 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
@ -4,7 +4,5 @@
|
||||
# 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)
|
||||
|
@ -0,0 +1,4 @@
|
||||
dependencies:
|
||||
espressif/esp_modem:
|
||||
version: "^1.0.1"
|
||||
override_path: "../../../"
|
@ -2,7 +2,5 @@
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS "../..")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(modem_tcp_client)
|
||||
|
@ -9,6 +9,20 @@ This example could be used in two different configurations:
|
||||
1) Custom TCP transport: Implements a TCP transport in form of AT commands and uses it as custom transport for mqtt client.
|
||||
2) Localhost listener: Uses standard transports to connect and forwards socket layer data from the client to the modem using AT commands.
|
||||
|
||||
### Custom TCP transport
|
||||
|
||||
This configuration expects that the network library, that is used to communicate with the endpoint uses `tcp_transport` component. In this example, we use `esp-mqtt` which supports custom transports so that we can implement a transport layer that communicate on TCP layer using AT commands. If we want to use TLS, we could add an SSL layer on top of this TCP layer.
|
||||
|
||||
To enable this mode, please set `EXAMPLE_CUSTOM_TCP_TRANSPORT=y`
|
||||
|
||||

|
||||
|
||||
### Localhost listener
|
||||
|
||||
This configuration could be used with any network library, which is connecting to a localhost endpoint instead of remote one. This example creates a localhost listener which basically mimics the remote endpoint by forwarding the traffic between the library and the TCP/socket layer of the modem (which is already secure if the TLS is used in the network library)
|
||||
|
||||

|
||||
|
||||
### Supported IDF versions
|
||||
|
||||
This example is supported from IDF `v5.0`.
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 137 KiB |
Binary file not shown.
After Width: | Height: | Size: 123 KiB |
@ -0,0 +1,4 @@
|
||||
dependencies:
|
||||
espressif/esp_modem:
|
||||
version: "^1.0.1"
|
||||
override_path: "../../../"
|
@ -2,7 +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/project.cmake)
|
||||
project(pppos_client)
|
||||
|
@ -48,6 +48,13 @@ menu "Example Configuration"
|
||||
bool "A7670"
|
||||
help
|
||||
A7670X is Multi-Band LTE-FDD/LTE-TDD/GSM/GPRS/EDGE module.
|
||||
|
||||
config EXAMPLE_MODEM_DEVICE_CUSTOM
|
||||
select ESP_MODEM_ADD_CUSTOM_MODULE
|
||||
bool "Custom device"
|
||||
help
|
||||
This demonstrates use of a custom device in C-API.
|
||||
|
||||
endchoice
|
||||
|
||||
config EXAMPLE_MODEM_PPP_APN
|
||||
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "cxx_include/esp_modem_api.hpp"
|
||||
#include "cxx_include/esp_modem_command_library_utils.hpp"
|
||||
|
||||
/**
|
||||
* @brief Definition of a custom module based on some already defined module
|
||||
* Here we use GenericModule, but you can use any kind of device
|
||||
* that is closer to your CustomModule.
|
||||
*/
|
||||
class SIM7600_WITH_TIME: public GenericModule {
|
||||
/**
|
||||
* @brief Need to reuse the constructors of our ancestor
|
||||
*/
|
||||
using GenericModule::GenericModule;
|
||||
public:
|
||||
/**
|
||||
* @brief New command that is not defined in the GenericModule
|
||||
*/
|
||||
command_result get_time(std::string &time)
|
||||
{
|
||||
return esp_modem::dce_commands::generic_get_string(dte.get(), "AT+CCLK?\r", time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This command is already defined in the GenericModule
|
||||
*
|
||||
* Here we just modify get_signal_quality() to return zeroes
|
||||
* for demonstration purpose only, since it's called within this example
|
||||
*/
|
||||
command_result get_signal_quality(int &rssi, int &ber) override
|
||||
{
|
||||
rssi = ber = 0;
|
||||
return esp_modem::command_result::OK;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief esp_modem_create_custom_dce() needs to be defined, as it is called in C-API wrapper when creating esp_modem_dce
|
||||
*
|
||||
* This uses public factory function for creating a common DCE with our CustomModule. Creating raw DCE pointer is only needed
|
||||
* for the C-API wrapper; C++API users would create DCE (any kind of smart pointer) directly with
|
||||
* Factory::create_unique_dce_from<CustomModule>(dce_config, std::move(dte), netif);
|
||||
*/
|
||||
DCE *esp_modem_create_custom_dce(const esp_modem_dce_config_t *dce_config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
|
||||
{
|
||||
return dce_factory::Factory::create_unique_dce_from<SIM7600_WITH_TIME, DCE *>(dce_config, std::move(dte), netif);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This API is only needed for extending standard C-API, since we added get_time() method to our CustomModule
|
||||
*
|
||||
* @note This header is included from esp_modem_c_api.cpp, so it could use ESP_MODEM_C_API_STR_MAX macro
|
||||
* indicating maximum C-API string size
|
||||
*
|
||||
* @note In order to access the newly added API get_time(), we have to static_cast<> the GenericModule from DCE
|
||||
* to our CustomModule.
|
||||
* Alternatively we could use the modem Factory to build our specific DCE_T<CustomModule>, but in that case
|
||||
* we couldn't use our C-API wrappers which expect DCE type, DCE_T<GenericModule> with lib commands (this alternative
|
||||
* is cleaner, but more suitable for C++ users)
|
||||
*/
|
||||
extern "C" esp_err_t esp_modem_get_time(esp_modem_dce_t *dce_wrap, char *p_time)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string time{ESP_MODEM_C_API_STR_MAX};
|
||||
auto ret = command_response_to_esp_err(static_cast<SIM7600_WITH_TIME *>(dce_wrap->dce->get_module())->get_time(time));
|
||||
if (ret == ESP_OK && !time.empty()) {
|
||||
strlcpy(p_time, time.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -37,6 +37,10 @@ static const int CONNECT_BIT = BIT0;
|
||||
static const int GOT_DATA_BIT = BIT2;
|
||||
static const int USB_DISCONNECTED_BIT = BIT3; // Used only with USB DTE but we define it unconditionally, to avoid too many #ifdefs in the code
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_MODEM_DEVICE_CUSTOM
|
||||
esp_err_t esp_modem_get_time(esp_modem_dce_t *dce_wrap, char *p_time);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
|
||||
#include "esp_modem_usb_c_api.h"
|
||||
#include "esp_modem_usb_config.h"
|
||||
@ -105,8 +109,8 @@ static void on_ppp_changed(void *arg, esp_event_base_t event_base,
|
||||
ESP_LOGI(TAG, "PPP state changed event %" PRIu32, event_id);
|
||||
if (event_id == NETIF_PPP_ERRORUSER) {
|
||||
/* User interrupted event from esp-netif */
|
||||
esp_netif_t *netif = event_data;
|
||||
ESP_LOGI(TAG, "User interrupted event from netif:%p", netif);
|
||||
esp_netif_t **p_netif = event_data;
|
||||
ESP_LOGI(TAG, "User interrupted event from netif:%p", *p_netif);
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,6 +196,9 @@ void app_main(void)
|
||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for the SIM7600 module...");
|
||||
esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_SIM7600, &dte_config, &dce_config, esp_netif);
|
||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_CUSTOM == 1
|
||||
ESP_LOGI(TAG, "Initializing esp_modem with custom module...");
|
||||
esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_CUSTOM, &dte_config, &dce_config, esp_netif);
|
||||
#else
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for a generic module...");
|
||||
esp_modem_dce_t *dce = esp_modem_new(&dte_config, &dce_config, esp_netif);
|
||||
@ -258,6 +265,18 @@ void app_main(void)
|
||||
}
|
||||
ESP_LOGI(TAG, "Signal quality: rssi=%d, ber=%d", rssi, ber);
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_MODEM_DEVICE_CUSTOM
|
||||
{
|
||||
char time[64];
|
||||
err = esp_modem_get_time(dce, time);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_modem_get_time failed with %d %s", err, esp_err_to_name(err));
|
||||
return;
|
||||
}
|
||||
ESP_LOGI(TAG, "esp_modem_get_time: %s", time);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_SEND_MSG
|
||||
if (esp_modem_sms_txt_mode(dce, true) != ESP_OK || esp_modem_sms_character_set(dce) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Setting text mode or GSM character set failed");
|
||||
|
@ -0,0 +1,14 @@
|
||||
CONFIG_IDF_TARGET="esp32s2"
|
||||
# Override some defaults to enable PPP
|
||||
CONFIG_LWIP_PPP_SUPPORT=y
|
||||
CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y
|
||||
CONFIG_LWIP_PPP_PAP_SUPPORT=y
|
||||
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
||||
CONFIG_LWIP_PPP_ENABLE_IPV6=n
|
||||
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y
|
||||
CONFIG_EXAMPLE_MODEM_DEVICE_A7670=y
|
||||
CONFIG_EXAMPLE_MODEM_PPP_APN="lpwa.vodafone.com"
|
||||
CONFIG_EXAMPLE_MODEM_PPP_AUTH_NONE=y
|
||||
CONFIG_EXAMPLE_MQTT_TEST_TOPIC="/ci/esp-modem/pppos-client"
|
||||
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
|
||||
CONFIG_ESP32_PANIC_PRINT_HALT=y
|
@ -3,7 +3,5 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS "../..")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(simple_cmux_client)
|
||||
|
@ -0,0 +1,4 @@
|
||||
dependencies:
|
||||
espressif/esp_modem:
|
||||
version: "^1.0.1"
|
||||
override_path: "../../../"
|
@ -1,6 +1,9 @@
|
||||
version: "1.0.3"
|
||||
description: esp modem
|
||||
version: "1.0.4"
|
||||
description: Library for communicating with cellular modems in command and data modes
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_modem
|
||||
issues: https://github.com/espressif/esp-protocols/issues
|
||||
documentation: https://docs.espressif.com/projects/esp-protocols/esp_modem/docs/latest/index.html
|
||||
repository: https://github.com/espressif/esp-protocols.git
|
||||
dependencies:
|
||||
# Required IDF version
|
||||
idf:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -12,6 +12,7 @@
|
||||
* @brief DCE modem factory
|
||||
*/
|
||||
|
||||
#define esp_modem_create_dce_from dce_factory::Factory::create_unique_dce_from
|
||||
|
||||
namespace esp_modem::dce_factory {
|
||||
|
||||
@ -236,12 +237,12 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T_Module>
|
||||
static std::unique_ptr<DCE> create_unique_dce_from(const esp_modem::dce_config *config,
|
||||
std::shared_ptr<esp_modem::DTE> dte,
|
||||
esp_netif_t *netif)
|
||||
template <typename T_Module, typename Ptr = std::unique_ptr<DCE>>
|
||||
static Ptr create_unique_dce_from(const esp_modem::dce_config *config,
|
||||
std::shared_ptr<esp_modem::DTE> dte,
|
||||
esp_netif_t *netif)
|
||||
{
|
||||
return build_generic_DCE<T_Module, DCE, std::unique_ptr<DCE>>(config, std::move(dte), netif);
|
||||
return build_generic_DCE<T_Module, DCE, Ptr>(config, std::move(dte), netif);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -76,6 +76,7 @@ public:
|
||||
* @param command Command to be sent
|
||||
* @param got_line callback if a line received
|
||||
* @param time_ms timeout in milliseconds
|
||||
* @param separator Character treated as a line separator, typically '\n'
|
||||
* @return OK, FAIL or TIMEOUT
|
||||
*/
|
||||
virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0;
|
||||
|
@ -53,6 +53,7 @@ typedef enum esp_modem_dce_device {
|
||||
ESP_MODEM_DCE_SIM7000,
|
||||
ESP_MODEM_DCE_BG96,
|
||||
ESP_MODEM_DCE_SIM800,
|
||||
ESP_MODEM_DCE_CUSTOM
|
||||
} esp_modem_dce_device_t;
|
||||
|
||||
/**
|
||||
|
@ -25,8 +25,8 @@ ESP_MODEM_DECLARE_DCE_COMMAND(sync, command_result, 0) \
|
||||
\
|
||||
/**
|
||||
* @brief Reads the operator name
|
||||
* @param[out] operator name
|
||||
* @param[out] access technology
|
||||
* @param[out] name operator name
|
||||
* @param[out] act access technology
|
||||
* @return OK, FAIL or TIMEOUT
|
||||
*/ \
|
||||
ESP_MODEM_DECLARE_DCE_COMMAND(get_operator_name, command_result, 2, STRING_OUT(p1, name), INT_OUT(p2, act)) \
|
||||
@ -46,7 +46,7 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_pin, command_result, 1, STRING_IN(p1, pin)) \
|
||||
\
|
||||
/**
|
||||
* @brief Execute the supplied AT command
|
||||
* @param[in] at AT command
|
||||
* @param[in] cmd AT command
|
||||
* @param[out] out Command output string
|
||||
* @param[in] timeout AT command timeout in milliseconds
|
||||
* @return OK, FAIL or TIMEOUT
|
||||
@ -252,6 +252,8 @@ ESP_MODEM_DECLARE_DCE_COMMAND(set_preferred_mode, command_result, 1, INT_IN(p1,
|
||||
/**
|
||||
* @brief Set network bands for CAT-M or NB-IoT
|
||||
* @param[in] mode CAT-M or NB-IoT
|
||||
* @param[in] bands bitmap in hex representing bands
|
||||
* @param[in] size size of teh bands bitmap
|
||||
* @return OK, FAIL or TIMEOUT
|
||||
*/ \
|
||||
ESP_MODEM_DECLARE_DCE_COMMAND(set_network_bands, command_result, 3, STRING_IN(p1, mode), INTEGER_LIST_IN(p2, bands), INT_IN(p3, size)) \
|
||||
|
@ -1,425 +1,436 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "uart_terminal.hpp"
|
||||
#include "esp_log.h"
|
||||
#include "cxx_include/esp_modem_api.hpp"
|
||||
#include "cxx_include/esp_modem_dce_factory.hpp"
|
||||
#include "esp_modem_c_api_types.h"
|
||||
#include "esp_modem_config.h"
|
||||
#include "exception_stub.hpp"
|
||||
#include "esp_private/c_api_wrapper.hpp"
|
||||
#include "cstring"
|
||||
|
||||
#ifndef ESP_MODEM_C_API_STR_MAX
|
||||
#define ESP_MODEM_C_API_STR_MAX 64
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char *dest, const char *src, size_t len);
|
||||
#endif
|
||||
|
||||
//
|
||||
// C API definitions
|
||||
using namespace esp_modem;
|
||||
|
||||
extern "C" esp_modem_dce_t *esp_modem_new_dev(esp_modem_dce_device_t module, const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif)
|
||||
{
|
||||
auto dce_wrap = new (std::nothrow) esp_modem_dce_wrap;
|
||||
if (dce_wrap == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto dte = create_uart_dte(dte_config);
|
||||
if (dte == nullptr) {
|
||||
delete dce_wrap;
|
||||
return nullptr;
|
||||
}
|
||||
dce_wrap->dte = dte;
|
||||
dce_factory::Factory f(convert_modem_enum(module));
|
||||
dce_wrap->dce = f.build(dce_config, std::move(dte), netif);
|
||||
if (dce_wrap->dce == nullptr) {
|
||||
delete dce_wrap;
|
||||
return nullptr;
|
||||
}
|
||||
dce_wrap->modem_type = convert_modem_enum(module);
|
||||
dce_wrap->dte_type = esp_modem_dce_wrap::modem_wrap_dte_type::UART;
|
||||
return dce_wrap;
|
||||
}
|
||||
|
||||
extern "C" esp_modem_dce_t *esp_modem_new(const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif)
|
||||
{
|
||||
return esp_modem_new_dev(ESP_MODEM_DCE_GENETIC, dte_config, dce_config, netif);
|
||||
}
|
||||
|
||||
extern "C" void esp_modem_destroy(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap) {
|
||||
delete dce_wrap->dce;
|
||||
delete dce_wrap;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_error_cb(esp_modem_dce_t *dce_wrap, esp_modem_terminal_error_cbt err_cb)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr || dce_wrap->dte == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (err_cb) {
|
||||
dce_wrap->dte->set_error_cb([err_cb](terminal_error err) {
|
||||
err_cb(convert_terminal_error_enum(err));
|
||||
});
|
||||
} else {
|
||||
dce_wrap->dte->set_error_cb(nullptr);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_sync(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->sync());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce_wrap, esp_modem_dce_mode_t mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
switch (mode) {
|
||||
case ESP_MODEM_MODE_DATA:
|
||||
return dce_wrap->dce->set_mode(modem_mode::DATA_MODE) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_COMMAND:
|
||||
return dce_wrap->dce->set_mode(modem_mode::COMMAND_MODE) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MODE) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_MODE) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL_EXIT:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_EXIT) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL_SWAP:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_SWAP) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL_DATA:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_DATA) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL_COMMAND:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_COMMAND) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t *dce_wrap, bool *pin)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return command_response_to_esp_err(dce_wrap->dce->read_pin(*pin));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_sms_txt_mode(esp_modem_dce_t *dce_wrap, bool txt)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return command_response_to_esp_err(dce_wrap->dce->sms_txt_mode(txt));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string number_str(number);
|
||||
std::string message_str(message);
|
||||
return command_response_to_esp_err(dce_wrap->dce->send_sms(number_str, message_str));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_sms_character_set(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return command_response_to_esp_err(dce_wrap->dce->sms_character_set());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string pin_str(pin);
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_pin(pin_str));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string out;
|
||||
std::string at_str(at);
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->at(at_str, out, timeout));
|
||||
if ((p_out != NULL) && (!out.empty())) {
|
||||
strlcpy(p_out, out.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_signal_quality(esp_modem_dce_t *dce_wrap, int *rssi, int *ber)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->get_signal_quality(*rssi, *ber));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_imsi(esp_modem_dce_t *dce_wrap, char *p_imsi)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string imsi;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_imsi(imsi));
|
||||
if (ret == ESP_OK && !imsi.empty()) {
|
||||
strlcpy(p_imsi, imsi.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_flow_control(esp_modem_dce_t *dce_wrap, int dce_flow, int dte_flow)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_flow_control(dce_flow, dte_flow));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_store_profile(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->store_profile());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_imei(esp_modem_dce_t *dce_wrap, char *p_imei)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string imei;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_imei(imei));
|
||||
if (ret == ESP_OK && !imei.empty()) {
|
||||
strlcpy(p_imei, imei.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_operator_name(esp_modem_dce_t *dce_wrap, char *p_name, int *p_act)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_name == nullptr || p_act == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string name;
|
||||
int act;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_operator_name(name, act));
|
||||
if (ret == ESP_OK && !name.empty()) {
|
||||
strlcpy(p_name, name.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
*p_act = act;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_module_name(esp_modem_dce_t *dce_wrap, char *p_name)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string name;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_module_name(name));
|
||||
if (ret == ESP_OK && !name.empty()) {
|
||||
strlcpy(p_name, name.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_battery_status(esp_modem_dce_t *dce_wrap, int *p_volt, int *p_bcs, int *p_bcl)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_bcs == nullptr || p_bcl == nullptr || p_volt == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int bcs, bcl, volt;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_battery_status(volt, bcs, bcl));
|
||||
if (ret == ESP_OK) {
|
||||
*p_volt = volt;
|
||||
*p_bcs = bcs;
|
||||
*p_bcl = bcl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_power_down(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->power_down());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string operator_str(oper);
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_operator(mode, format, operator_str));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_network_attachment_state(esp_modem_dce_t *dce_wrap, int state)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_network_attachment_state(state));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_network_attachment_state(esp_modem_dce_t *dce_wrap, int *p_state)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int state;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_attachment_state(state));
|
||||
if (ret == ESP_OK) {
|
||||
*p_state = state;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_radio_state(esp_modem_dce_t *dce_wrap, int state)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_radio_state(state));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_radio_state(esp_modem_dce_t *dce_wrap, int *p_state)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int state;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_radio_state(state));
|
||||
if (ret == ESP_OK) {
|
||||
*p_state = state;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_network_mode(esp_modem_dce_t *dce_wrap, int mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_network_mode(mode));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_preferred_mode(esp_modem_dce_t *dce_wrap, int mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_preferred_mode(mode));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string mode_str(mode);
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_network_bands(mode, bands, size));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_network_system_mode(esp_modem_dce_t *dce_wrap, int *p_mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int mode;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_system_mode(mode));
|
||||
if (ret == ESP_OK) {
|
||||
*p_mode = mode;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_gnss_power_mode(esp_modem_dce_t *dce_wrap, int mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_gnss_power_mode(mode));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_gnss_power_mode(esp_modem_dce_t *dce_wrap, int *p_mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int mode;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_gnss_power_mode(mode));
|
||||
if (ret == ESP_OK) {
|
||||
*p_mode = mode;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_reset(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
return command_response_to_esp_err(dce_wrap->dce->reset());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_pdp_context(esp_modem_dce_t *dce_wrap, esp_modem_PdpContext_t *c_api_pdp)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_modem::PdpContext pdp{c_api_pdp->apn};
|
||||
pdp.context_id = c_api_pdp->context_id;
|
||||
pdp.protocol_type = c_api_pdp->protocol_type;
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_pdp_context(pdp));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_command(esp_modem_dce_t *dce_wrap, const char *command, esp_err_t(*got_line_fn)(uint8_t *data, size_t len), uint32_t timeout_ms)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr || command == nullptr || got_line_fn == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string cmd(command);
|
||||
return command_response_to_esp_err(dce_wrap->dce->command(cmd, [got_line_fn](uint8_t *data, size_t len) {
|
||||
switch (got_line_fn(data, len)) {
|
||||
case ESP_OK:
|
||||
return command_result::OK;
|
||||
case ESP_FAIL:
|
||||
return command_result::FAIL;
|
||||
default:
|
||||
return command_result::TIMEOUT;
|
||||
}
|
||||
}, timeout_ms));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_baud(esp_modem_dce_t *dce_wrap, int baud)
|
||||
{
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_baud(baud));
|
||||
}
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "uart_terminal.hpp"
|
||||
#include "esp_log.h"
|
||||
#include "cxx_include/esp_modem_api.hpp"
|
||||
#include "cxx_include/esp_modem_dce_factory.hpp"
|
||||
#include "esp_modem_c_api_types.h"
|
||||
#include "esp_modem_config.h"
|
||||
#include "exception_stub.hpp"
|
||||
#include "esp_private/c_api_wrapper.hpp"
|
||||
|
||||
#ifndef ESP_MODEM_C_API_STR_MAX
|
||||
#define ESP_MODEM_C_API_STR_MAX 64
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char *dest, const char *src, size_t len);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE
|
||||
#include CONFIG_ESP_MODEM_CUSTOM_MODULE_HEADER
|
||||
#endif
|
||||
|
||||
//
|
||||
// C API definitions
|
||||
using namespace esp_modem;
|
||||
|
||||
extern "C" esp_modem_dce_t *esp_modem_new_dev(esp_modem_dce_device_t module, const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif)
|
||||
{
|
||||
auto dce_wrap = new (std::nothrow) esp_modem_dce_wrap;
|
||||
if (dce_wrap == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto dte = create_uart_dte(dte_config);
|
||||
if (dte == nullptr) {
|
||||
delete dce_wrap;
|
||||
return nullptr;
|
||||
}
|
||||
dce_wrap->dte = dte;
|
||||
#ifdef CONFIG_ESP_MODEM_ADD_CUSTOM_MODULE
|
||||
if (module == ESP_MODEM_DCE_CUSTOM) {
|
||||
dce_wrap->dce = esp_modem_create_custom_dce(dce_config, dte, netif);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
dce_factory::Factory f(convert_modem_enum(module));
|
||||
dce_wrap->dce = f.build(dce_config, std::move(dte), netif);
|
||||
}
|
||||
if (dce_wrap->dce == nullptr) {
|
||||
delete dce_wrap;
|
||||
return nullptr;
|
||||
}
|
||||
dce_wrap->modem_type = convert_modem_enum(module);
|
||||
dce_wrap->dte_type = esp_modem_dce_wrap::modem_wrap_dte_type::UART;
|
||||
return dce_wrap;
|
||||
}
|
||||
|
||||
extern "C" esp_modem_dce_t *esp_modem_new(const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif)
|
||||
{
|
||||
return esp_modem_new_dev(ESP_MODEM_DCE_GENETIC, dte_config, dce_config, netif);
|
||||
}
|
||||
|
||||
extern "C" void esp_modem_destroy(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap) {
|
||||
delete dce_wrap->dce;
|
||||
delete dce_wrap;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_error_cb(esp_modem_dce_t *dce_wrap, esp_modem_terminal_error_cbt err_cb)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr || dce_wrap->dte == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (err_cb) {
|
||||
dce_wrap->dte->set_error_cb([err_cb](terminal_error err) {
|
||||
err_cb(convert_terminal_error_enum(err));
|
||||
});
|
||||
} else {
|
||||
dce_wrap->dte->set_error_cb(nullptr);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_sync(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->sync());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce_wrap, esp_modem_dce_mode_t mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
switch (mode) {
|
||||
case ESP_MODEM_MODE_DATA:
|
||||
return dce_wrap->dce->set_mode(modem_mode::DATA_MODE) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_COMMAND:
|
||||
return dce_wrap->dce->set_mode(modem_mode::COMMAND_MODE) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MODE) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_MODE) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL_EXIT:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_EXIT) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL_SWAP:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_SWAP) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL_DATA:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_DATA) ? ESP_OK : ESP_FAIL;
|
||||
case ESP_MODEM_MODE_CMUX_MANUAL_COMMAND:
|
||||
return dce_wrap->dce->set_mode(modem_mode::CMUX_MANUAL_COMMAND) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t *dce_wrap, bool *pin)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return command_response_to_esp_err(dce_wrap->dce->read_pin(*pin));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_sms_txt_mode(esp_modem_dce_t *dce_wrap, bool txt)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return command_response_to_esp_err(dce_wrap->dce->sms_txt_mode(txt));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string number_str(number);
|
||||
std::string message_str(message);
|
||||
return command_response_to_esp_err(dce_wrap->dce->send_sms(number_str, message_str));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_sms_character_set(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return command_response_to_esp_err(dce_wrap->dce->sms_character_set());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string pin_str(pin);
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_pin(pin_str));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_at(esp_modem_dce_t *dce_wrap, const char *at, char *p_out, int timeout)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string out;
|
||||
std::string at_str(at);
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->at(at_str, out, timeout));
|
||||
if ((p_out != NULL) && (!out.empty())) {
|
||||
strlcpy(p_out, out.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_signal_quality(esp_modem_dce_t *dce_wrap, int *rssi, int *ber)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->get_signal_quality(*rssi, *ber));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_imsi(esp_modem_dce_t *dce_wrap, char *p_imsi)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string imsi;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_imsi(imsi));
|
||||
if (ret == ESP_OK && !imsi.empty()) {
|
||||
strlcpy(p_imsi, imsi.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_flow_control(esp_modem_dce_t *dce_wrap, int dce_flow, int dte_flow)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_flow_control(dce_flow, dte_flow));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_store_profile(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->store_profile());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_imei(esp_modem_dce_t *dce_wrap, char *p_imei)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string imei;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_imei(imei));
|
||||
if (ret == ESP_OK && !imei.empty()) {
|
||||
strlcpy(p_imei, imei.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_operator_name(esp_modem_dce_t *dce_wrap, char *p_name, int *p_act)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_name == nullptr || p_act == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string name;
|
||||
int act;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_operator_name(name, act));
|
||||
if (ret == ESP_OK && !name.empty()) {
|
||||
strlcpy(p_name, name.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
*p_act = act;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_module_name(esp_modem_dce_t *dce_wrap, char *p_name)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string name;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_module_name(name));
|
||||
if (ret == ESP_OK && !name.empty()) {
|
||||
strlcpy(p_name, name.c_str(), ESP_MODEM_C_API_STR_MAX);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_battery_status(esp_modem_dce_t *dce_wrap, int *p_volt, int *p_bcs, int *p_bcl)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr || p_bcs == nullptr || p_bcl == nullptr || p_volt == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int bcs, bcl, volt;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_battery_status(volt, bcs, bcl));
|
||||
if (ret == ESP_OK) {
|
||||
*p_volt = volt;
|
||||
*p_bcs = bcs;
|
||||
*p_bcl = bcl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_power_down(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->power_down());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_operator(esp_modem_dce_t *dce_wrap, int mode, int format, const char *oper)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string operator_str(oper);
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_operator(mode, format, operator_str));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_network_attachment_state(esp_modem_dce_t *dce_wrap, int state)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_network_attachment_state(state));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_network_attachment_state(esp_modem_dce_t *dce_wrap, int *p_state)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int state;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_attachment_state(state));
|
||||
if (ret == ESP_OK) {
|
||||
*p_state = state;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_radio_state(esp_modem_dce_t *dce_wrap, int state)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_radio_state(state));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_radio_state(esp_modem_dce_t *dce_wrap, int *p_state)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int state;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_radio_state(state));
|
||||
if (ret == ESP_OK) {
|
||||
*p_state = state;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_network_mode(esp_modem_dce_t *dce_wrap, int mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_network_mode(mode));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_preferred_mode(esp_modem_dce_t *dce_wrap, int mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_preferred_mode(mode));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_network_bands(esp_modem_dce_t *dce_wrap, const char *mode, const int *bands, int size)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string mode_str(mode);
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_network_bands(mode, bands, size));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_network_system_mode(esp_modem_dce_t *dce_wrap, int *p_mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int mode;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_network_system_mode(mode));
|
||||
if (ret == ESP_OK) {
|
||||
*p_mode = mode;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_gnss_power_mode(esp_modem_dce_t *dce_wrap, int mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_gnss_power_mode(mode));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_get_gnss_power_mode(esp_modem_dce_t *dce_wrap, int *p_mode)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int mode;
|
||||
auto ret = command_response_to_esp_err(dce_wrap->dce->get_gnss_power_mode(mode));
|
||||
if (ret == ESP_OK) {
|
||||
*p_mode = mode;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_reset(esp_modem_dce_t *dce_wrap)
|
||||
{
|
||||
return command_response_to_esp_err(dce_wrap->dce->reset());
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_pdp_context(esp_modem_dce_t *dce_wrap, esp_modem_PdpContext_t *c_api_pdp)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_modem::PdpContext pdp{c_api_pdp->apn};
|
||||
pdp.context_id = c_api_pdp->context_id;
|
||||
pdp.protocol_type = c_api_pdp->protocol_type;
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_pdp_context(pdp));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_command(esp_modem_dce_t *dce_wrap, const char *command, esp_err_t(*got_line_fn)(uint8_t *data, size_t len), uint32_t timeout_ms)
|
||||
{
|
||||
if (dce_wrap == nullptr || dce_wrap->dce == nullptr || command == nullptr || got_line_fn == nullptr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
std::string cmd(command);
|
||||
return command_response_to_esp_err(dce_wrap->dce->command(cmd, [got_line_fn](uint8_t *data, size_t len) {
|
||||
switch (got_line_fn(data, len)) {
|
||||
case ESP_OK:
|
||||
return command_result::OK;
|
||||
case ESP_FAIL:
|
||||
return command_result::FAIL;
|
||||
default:
|
||||
return command_result::TIMEOUT;
|
||||
}
|
||||
}, timeout_ms));
|
||||
}
|
||||
|
||||
extern "C" esp_err_t esp_modem_set_baud(esp_modem_dce_t *dce_wrap, int baud)
|
||||
{
|
||||
return command_response_to_esp_err(dce_wrap->dce->set_baud(baud));
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ DTE::DTE(std::unique_ptr<Terminal> terminal):
|
||||
DTE::DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s):
|
||||
buffer(config->dte_buffer_size),
|
||||
cmux_term(nullptr), primary_term(std::move(t)), secondary_term(std::move(s)),
|
||||
mode(modem_mode::UNDEF)
|
||||
mode(modem_mode::DUAL_MODE)
|
||||
{
|
||||
set_command_callbacks();
|
||||
}
|
||||
@ -41,7 +41,7 @@ DTE::DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> t, std::u
|
||||
DTE::DTE(std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s):
|
||||
buffer(dte_default_buffer_size),
|
||||
cmux_term(nullptr), primary_term(std::move(t)), secondary_term(std::move(s)),
|
||||
mode(modem_mode::UNDEF)
|
||||
mode(modem_mode::DUAL_MODE)
|
||||
{
|
||||
set_command_callbacks();
|
||||
}
|
||||
@ -78,9 +78,9 @@ void DTE::set_command_callbacks()
|
||||
if (command_cb.process_line(data, 0, len)) {
|
||||
return true;
|
||||
}
|
||||
// cannot inflate and the processing hasn't finishes in the first iteration -> report a failure
|
||||
command_cb.give_up();
|
||||
return true;
|
||||
// cannot inflate and the processing hasn't finishes in the first iteration, but continue
|
||||
// (will post next fragments to the parser, since we might be just missing a last token or OK
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
// data == nullptr: Terminals which request users to read current data
|
||||
@ -313,6 +313,7 @@ void DTE::on_read(got_line_cb on_read_cb)
|
||||
if (on_read_cb == nullptr) {
|
||||
primary_term->set_read_cb(nullptr);
|
||||
internal_lock.unlock();
|
||||
set_command_callbacks();
|
||||
return;
|
||||
}
|
||||
internal_lock.lock();
|
||||
|
@ -1,10 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
lwip=$1
|
||||
lwip_uri=$2
|
||||
lwip_contrib=$3
|
||||
idf_version=$1
|
||||
component=$2
|
||||
|
||||
wget --no-verbose ${lwip_uri}/${lwip}.zip
|
||||
unzip -oq ${lwip}.zip
|
||||
wget --no-verbose ${lwip_uri}/${lwip_contrib}.zip
|
||||
unzip -oq ${lwip_contrib}.zip
|
||||
if [[ "$idf_version" == "release-v4.3" ]] && [[ "$component" == "esp_modem" ]]; then
|
||||
lwip=lwip-2.1.2
|
||||
lwip_uri=http://download.savannah.nongnu.org/releases/lwip
|
||||
lwip_contrib=contrib-2.1.0
|
||||
|
||||
wget --no-verbose ${lwip_uri}/${lwip}.zip
|
||||
unzip -oq ${lwip}.zip
|
||||
wget --no-verbose ${lwip_uri}/${lwip_contrib}.zip
|
||||
unzip -oq ${lwip_contrib}.zip
|
||||
|
||||
apt-get update && apt-get install -y gcc-8 g++-8
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8
|
||||
rm /usr/bin/gcov && ln -s /usr/bin/gcov-8 /usr/bin/gcov
|
||||
export LWIP_PATH=`pwd`/$lwip
|
||||
export LWIP_CONTRIB_PATH=`pwd`/$lwip_contrib
|
||||
fi
|
||||
|
@ -1 +1,6 @@
|
||||
CONFIG_IDF_TARGET="linux"
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||||
CONFIG_COMPILER_CXX_RTTI=y
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0
|
||||
CONFIG_COMPILER_STACK_CHECK_NONE=y
|
||||
CONFIG_GCOV_ENABLED=y
|
||||
|
5
components/esp_modem/test/host_test/sdkconfig.ci.linux
Normal file
5
components/esp_modem/test/host_test/sdkconfig.ci.linux
Normal file
@ -0,0 +1,5 @@
|
||||
CONFIG_IDF_TARGET="linux"
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||||
CONFIG_COMPILER_CXX_RTTI=y
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0
|
||||
CONFIG_COMPILER_STACK_CHECK_NONE=y
|
@ -1,8 +0,0 @@
|
||||
#
|
||||
# Main component makefile.
|
||||
#
|
||||
# This Makefile can be left empty. By default, it will take the sources in the
|
||||
# src/ directory, compile them and link them into lib(subdirectory_name).a
|
||||
# in the build directory. This behaviour is entirely configurable,
|
||||
# please read the ESP-IDF documents if you need to do this.
|
||||
#
|
@ -64,8 +64,8 @@ static void on_ppp_changed(void *arg, esp_event_base_t event_base,
|
||||
ESP_LOGI(TAG, "PPP state changed event %" PRId32, event_id);
|
||||
if (event_id == NETIF_PPP_ERRORUSER) {
|
||||
/* User interrupted event from esp-netif */
|
||||
esp_netif_t *netif = static_cast<esp_netif_t *>(event_data);
|
||||
ESP_LOGI(TAG, "User interrupted event from netif:%p", netif);
|
||||
auto p_netif = static_cast<esp_netif_t **>(event_data);
|
||||
ESP_LOGI(TAG, "User interrupted event from netif:%p", *p_netif);
|
||||
xEventGroupSetBits(event_group, 2);
|
||||
}
|
||||
}
|
||||
|
8
components/esp_mqtt_cxx/.cz.yaml
Normal file
8
components/esp_mqtt_cxx/.cz.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
commitizen:
|
||||
bump_message: 'bump(mqtt_cxx): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py esp_mqtt_cxx
|
||||
tag_format: mqtt_cxx-v$version
|
||||
version: 0.2.0
|
||||
version_files:
|
||||
- idf_component.yml
|
@ -1,5 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## [0.2.0](https://github.com/espressif/esp-protocols/commits/mqtt_cxx-v0.2.0)
|
||||
|
||||
### Features
|
||||
|
||||
- configure client authentication via certificate/key or secure element ([ee09ff4](https://github.com/espressif/esp-protocols/commit/ee09ff4))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- removed Wno-format flag and fixed formatting warnings ([c48e442](https://github.com/espressif/esp-protocols/commit/c48e442))
|
||||
- Removes meaningless printf on subscribed handler (#358) ([bac742d](https://github.com/espressif/esp-protocols/commit/bac742d), [#356](https://github.com/espressif/esp-protocols/issues/356))
|
||||
- Removes unused type for configuration ([839c79d](https://github.com/espressif/esp-protocols/commit/839c79d))
|
||||
- added idf_component.yml for examples ([d273e10](https://github.com/espressif/esp-protocols/commit/d273e10))
|
||||
- Reintroduce missing CHANGELOGs ([200cbb3](https://github.com/espressif/esp-protocols/commit/200cbb3), [#235](https://github.com/espressif/esp-protocols/issues/235))
|
||||
|
||||
### Updated
|
||||
|
||||
- docs(common): updated component and example links ([f48d9b2](https://github.com/espressif/esp-protocols/commit/f48d9b2))
|
||||
- docs(esp_mqtt_cxx): updated documentation and deployment file ([a547ec8](https://github.com/espressif/esp-protocols/commit/a547ec8))
|
||||
- docs(common): improving documentation ([ca3fce0](https://github.com/espressif/esp-protocols/commit/ca3fce0))
|
||||
- Add homepage URL and License to all components ([ef3f0ee](https://github.com/espressif/esp-protocols/commit/ef3f0ee))
|
||||
|
||||
## [0.1.0](https://github.com/espressif/esp-protocols/commits/1407dfc)
|
||||
|
||||
### Updated
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user