mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-03 13:46:33 +02:00
Compare commits
57 Commits
wifi_remot
...
eppp-v0.2.
Author | SHA1 | Date | |
---|---|---|---|
68da69e4d8 | |||
c6e2eb2dac | |||
a9dd78ffad | |||
eb09e42638 | |||
adafeae5cf | |||
d7eaa77b89 | |||
402176c9e0 | |||
085dd79079 | |||
a05fbc7ed9 | |||
ba35d14e43 | |||
2b64e80acd | |||
ac9972aa48 | |||
1c5a149b14 | |||
8d0152f612 | |||
b2272b410d | |||
5d43f9660f | |||
bdbf16c113 | |||
7f248bd03f | |||
dabd4bfd0e | |||
70fa3af771 | |||
5d69d3f0ac | |||
39d59032a2 | |||
e3418b5527 | |||
21d1540b76 | |||
186e258798 | |||
139166c2c5 | |||
7437d31368 | |||
d20255a40c | |||
6af6ca52a2 | |||
042533af90 | |||
732b1d5084 | |||
9e13870ad4 | |||
3f12ef6eea | |||
f1bc070b86 | |||
28c0e0b77b | |||
24ce86756d | |||
39dfe268a3 | |||
d96f45a1f9 | |||
90fdcfc340 | |||
7829e8f976 | |||
ce27c13352 | |||
eab58de630 | |||
fcb60806a9 | |||
22914d4b7b | |||
150a3ec06a | |||
c12616c91d | |||
f05c765e8b | |||
ed021a90d4 | |||
6393fcd79a | |||
c9439bd3d5 | |||
2c4c88b4fb | |||
d45c5cef9a | |||
afd98bb9c5 | |||
8f19c60c19 | |||
281e933808 | |||
f4bdf0ab6c | |||
eb84eed8d3 |
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.1"]
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3"]
|
||||
idf_target: ["esp32", "esp32s2"]
|
||||
example: ["asio_chat", "async_request", "socks4", "ssl_client_server", "tcp_echo_server", "udp_echo_server"]
|
||||
runs-on: ubuntu-22.04
|
||||
@ -64,7 +64,7 @@ jobs:
|
||||
name: Target tests
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0"]
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.2", "release-v5.3"]
|
||||
idf_target: ["esp32"]
|
||||
example: ["asio_chat", "tcp_echo_server", "udp_echo_server", "ssl_client_server"]
|
||||
needs: build_asio
|
||||
|
55
.github/workflows/clang-tidy.yml
vendored
Normal file
55
.github/workflows/clang-tidy.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
name: Run clang-tidy
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Run clang-tidy
|
||||
runs-on: ubuntu-20.04
|
||||
container: espressif/idf:latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Install esp-clang
|
||||
run: |
|
||||
${IDF_PATH}/tools/idf_tools.py --non-interactive install esp-clang
|
||||
- name: Install clang-tidy-sarif
|
||||
run: |
|
||||
curl -sSL https://github.com/psastras/sarif-rs/releases/download/clang-tidy-sarif-v0.3.3/clang-tidy-sarif-x86_64-unknown-linux-gnu -o clang-tidy-sarif
|
||||
chmod +x clang-tidy-sarif
|
||||
curl -sSL https://raw.githubusercontent.com/espressif/idf-extra-components/master/.github/filter_sarif.py -o filter_sarif.py
|
||||
- name: Install pyclang
|
||||
run: |
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install pyclang~=0.2.0
|
||||
- name: Run code analysis
|
||||
shell: bash
|
||||
env:
|
||||
IDF_TOOLCHAIN: clang
|
||||
IDF_TARGET: esp32
|
||||
working-directory: test_app
|
||||
run: |
|
||||
. ${IDF_PATH}/export.sh
|
||||
idf.py clang-check --include-paths $GITHUB_WORKSPACE --exclude-paths $PWD --run-clang-tidy-py run-clang-tidy
|
||||
cp warnings.txt ../
|
||||
- name: Convert clang-tidy results into SARIF output
|
||||
run: |
|
||||
export PATH=$PWD:$PATH
|
||||
./clang-tidy-sarif -o results.sarif.raw warnings.txt
|
||||
python3 filter_sarif.py -o results.sarif --include-prefix ${GITHUB_WORKSPACE}/ results.sarif.raw
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
path: |
|
||||
warnings.txt
|
||||
results.sarif
|
||||
results.sarif.raw
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
category: clang-tidy
|
@ -13,12 +13,12 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.1", "release-v5.0"]
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3"]
|
||||
idf_target: ["esp32"]
|
||||
test: [ { app: ifconfig-basic, path: "components/console_cmd_ifconfig/examples"}]
|
||||
include:
|
||||
- idf_ver: "latest"
|
||||
warning: "the choice symbol ETHERNET_PHY_LAN867X"
|
||||
warning: "the choice symbol ETHERNET_PHY_LAN867X\nis deprecated: Please use smi_gpio instead"
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
@ -33,6 +33,6 @@ jobs:
|
||||
shell: bash
|
||||
working-directory: ${{matrix.test.path}}
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
python ../../../ci/build_apps.py ./${{ matrix.test.app }} --target ${{ matrix.idf_target }} -vv --preserve-all --pytest-app
|
||||
|
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0"]
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3"]
|
||||
idf_target: ["esp32"]
|
||||
test: [ { app: ping-basic, path: "components/console_cmd_ping/examples" }]
|
||||
runs-on: ubuntu-22.04
|
||||
@ -27,6 +27,6 @@ jobs:
|
||||
shell: bash
|
||||
working-directory: ${{matrix.test.path}}
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
python ../../../ci/build_apps.py ./${{ matrix.test.app }} --target ${{ matrix.idf_target }} -vv --preserve-all --pytest-app
|
||||
|
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0"]
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3"]
|
||||
idf_target: ["esp32"]
|
||||
test: [ { app: wifi-basic, path: "components/console_cmd_wifi/examples" }]
|
||||
runs-on: ubuntu-22.04
|
||||
@ -27,6 +27,6 @@ jobs:
|
||||
shell: bash
|
||||
working-directory: ${{matrix.test.path}}
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
python ../../../ci/build_apps.py ./${{ matrix.test.app }} --target ${{ matrix.idf_target }} -vv --preserve-all --pytest-app
|
||||
|
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0"]
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3"]
|
||||
idf_target: ["esp32"]
|
||||
test: [ { app: console_basic, path: "components/console_simple_init/examples" }]
|
||||
runs-on: ubuntu-22.04
|
||||
@ -27,6 +27,6 @@ jobs:
|
||||
shell: bash
|
||||
working-directory: ${{matrix.test.path}}
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
python ../../../ci/build_apps.py ./${{ matrix.test.app }} --target ${{ matrix.idf_target }} -vv --preserve-all --pytest-app
|
||||
|
4
.github/workflows/eppp__build.yml
vendored
4
.github/workflows/eppp__build.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest"]
|
||||
idf_ver: ["latest", "release-v5.3"]
|
||||
test: [ { app: host, path: "examples/host" }, { app: slave, path: "examples/slave" }, { app: test_app, path: "test/test_app" }]
|
||||
runs-on: ubuntu-20.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
@ -23,6 +23,6 @@ jobs:
|
||||
- name: Build ${{ matrix.test.app }} with IDF-${{ matrix.idf_ver }}
|
||||
shell: bash
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
python ./ci/build_apps.py ./components/eppp_link/${{matrix.test.path}} -vv --preserve-all
|
||||
|
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build examples
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.1"]
|
||||
idf_ver: ["latest", "release-v5.1", "release-v5.2", "release-v5.3"]
|
||||
runs-on: ubuntu-22.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
steps:
|
||||
|
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0"]
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.2", "release-v5.3"]
|
||||
test: [ { app: example, path: "examples/query_advertise" }, { app: unit_test, path: "tests/unit_test" }, { app: test_app, path: "tests/test_apps" } ]
|
||||
runs-on: ubuntu-22.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
|
@ -13,16 +13,12 @@ jobs:
|
||||
name: Build examples
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v4.3", "release-v4.4", "release-v5.0"]
|
||||
idf_ver: ["latest", "release-v4.4", "release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3"]
|
||||
example: ["pppos_client", "modem_console", "modem_tcp_client", "ap_to_pppos", "simple_cmux_client"]
|
||||
exclude:
|
||||
- idf_ver: "release-v4.3"
|
||||
example: modem_tcp_client
|
||||
- idf_ver: "release-v4.4"
|
||||
example: modem_tcp_client
|
||||
include:
|
||||
- idf_ver: "release-v4.3"
|
||||
skip_config: usb
|
||||
- idf_ver: "release-v5.0"
|
||||
example: "simple_cmux_client"
|
||||
warning: "Warning: The smallest app partition is nearly full"
|
||||
@ -57,7 +53,7 @@ jobs:
|
||||
name: Build tests
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["release-v5.0", "release-v5.1", "latest"]
|
||||
idf_ver: ["release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "latest"]
|
||||
test: ["target", "target_ota", "target_iperf"]
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
4
.github/workflows/mqtt_cxx__build.yml
vendored
4
.github/workflows/mqtt_cxx__build.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0"]
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3"]
|
||||
idf_target: ["esp32"]
|
||||
test: [ { app: mqtt-basic, path: "components/esp_mqtt_cxx/examples" }]
|
||||
runs-on: ubuntu-22.04
|
||||
@ -27,6 +27,6 @@ jobs:
|
||||
shell: bash
|
||||
working-directory: ${{matrix.test.path}}
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
python ../../../ci/build_apps.py ./${{ matrix.test.app }} --target ${{ matrix.idf_target }} -vv --preserve-all --pytest-app
|
||||
|
2
.github/workflows/pre_commit_check.yml
vendored
2
.github/workflows/pre_commit_check.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
- name: Set up Python environment
|
||||
uses: actions/setup-python@master
|
||||
with:
|
||||
python-version: v3.7
|
||||
python-version: v3.8
|
||||
- name: Install python packages
|
||||
run: |
|
||||
pip install pre-commit
|
||||
|
6
.github/workflows/run-host-tests.yml
vendored
6
.github/workflows/run-host-tests.yml
vendored
@ -87,8 +87,10 @@ jobs:
|
||||
shell: bash
|
||||
if: ${{ inputs.run_coverage }}
|
||||
run: |
|
||||
apt-get update && apt-get install -y python3-pip rsync
|
||||
python -m pip install gcovr
|
||||
apt-get update && apt-get install -y rsync
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
python3 -m pip install gcovr
|
||||
cd $GITHUB_WORKSPACE/${{inputs.component_path}}
|
||||
component=$(basename ${{ inputs.component_path }})
|
||||
gcov `find . -name "$component*gcda"`
|
||||
|
4
.github/workflows/tls_cxx__build.yml
vendored
4
.github/workflows/tls_cxx__build.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.2", "release-v5.1"]
|
||||
idf_ver: ["latest", "release-v5.3", "release-v5.2", "release-v5.1"]
|
||||
test: [ { app: client, path: "examples/tls_client" }, { app: udp, path: "examples/udp_mutual_auth" }, { app: test, path: "tests/uart_mutual_auth" } ]
|
||||
runs-on: ubuntu-20.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
@ -25,6 +25,6 @@ jobs:
|
||||
- name: Build ${{ matrix.test.app }} with IDF-${{ matrix.idf_ver }}
|
||||
shell: bash
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
python ./ci/build_apps.py ./components/mbedtls_cxx/${{ matrix.test.path }} -vv --preserve-all
|
||||
|
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["release-v5.0", "release-v5.1", "latest"]
|
||||
idf_ver: ["release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "latest"]
|
||||
test: [ { app: example, path: "examples/target" }, { app: unit_test, path: "test" } ]
|
||||
runs-on: ubuntu-22.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
@ -51,7 +51,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
idf_ver: ["release-v5.0", "release-v5.1", "latest"]
|
||||
idf_ver: ["release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "latest"]
|
||||
idf_target: ["esp32"]
|
||||
test: [ { app: example, path: "examples/target" }, { app: unit_test, path: "test" } ]
|
||||
runs-on:
|
||||
|
6
.github/workflows/wifi_remote__build.yml
vendored
6
.github/workflows/wifi_remote__build.yml
vendored
@ -22,8 +22,8 @@ jobs:
|
||||
- name: Check that headers are the same as generated
|
||||
shell: bash
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
cd ./components/esp_wifi_remote/scripts
|
||||
python generate_and_check.py
|
||||
|
||||
@ -46,8 +46,8 @@ jobs:
|
||||
- name: Build ${{ matrix.test.app }} with IDF-${{ matrix.idf_ver }}
|
||||
shell: bash
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
python ./ci/build_apps.py ./components/esp_wifi_remote/${{matrix.test.path}} -vv --preserve-all
|
||||
|
||||
build_wifi_remote_example:
|
||||
@ -72,6 +72,6 @@ jobs:
|
||||
EXPECTED_WARNING: ${{ matrix.warning }}
|
||||
shell: bash
|
||||
run: |
|
||||
${IDF_PATH}/install.sh --enable-pytest
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
python ./ci/build_apps.py ./components/esp_wifi_remote/${{matrix.example.path}} -vv --preserve-all
|
||||
|
@ -48,7 +48,7 @@ repos:
|
||||
- id: check-copyright
|
||||
args: ['--ignore', 'ci/check_copyright_ignore.txt', '--config', 'ci/check_copyright_config.yaml']
|
||||
- repo: https://github.com/igrr/astyle_py.git
|
||||
rev: c0013808882a15a0c0c2c1a9b5c903866c53a653
|
||||
rev: v1.0.5
|
||||
hooks:
|
||||
- id: astyle_py
|
||||
args: ['--style=otbs', '--attach-namespaces', '--attach-classes', '--indent=spaces=4', '--convert-tabs', '--align-pointer=name', '--align-reference=name', '--keep-one-line-statements', '--pad-header', '--pad-oper', '--exclude-list=ci/ignore_astyle.txt']
|
||||
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(console): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py console_cmd_wifi
|
||||
tag_format: console_cmd_wifi-v$version
|
||||
version: 1.0.1
|
||||
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_cmd_wifi-v1.1.0)
|
||||
|
||||
### Features
|
||||
|
||||
- Added support to join pre-configured network ([bdbf16c1](https://github.com/espressif/esp-protocols/commit/bdbf16c1))
|
||||
|
||||
## [1.0.1](https://github.com/espressif/esp-protocols/commits/console_cmd_wifi-v1.0.1)
|
||||
|
||||
### Features
|
||||
|
@ -1,4 +1,8 @@
|
||||
idf_component_register(SRCS "console_wifi.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES esp_netif console esp_wifi
|
||||
WHOLE_ARCHIVE)
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES lwip
|
||||
PRIV_REQUIRES esp_netif console esp_wifi esp_timer)
|
||||
|
||||
if(CONFIG_WIFI_CMD_AUTO_REGISTRATION)
|
||||
target_link_libraries(${COMPONENT_LIB} "-u console_cmd_wifi_register")
|
||||
endif()
|
||||
|
22
components/console_cmd_wifi/Kconfig.projbuild
Normal file
22
components/console_cmd_wifi/Kconfig.projbuild
Normal file
@ -0,0 +1,22 @@
|
||||
menu "Wifi command Configuration"
|
||||
|
||||
config WIFI_CMD_AUTO_REGISTRATION
|
||||
bool "Enable Console command wifi Auto-registration"
|
||||
default y
|
||||
help
|
||||
Enabling this allows for the autoregistration of the wifi command.
|
||||
|
||||
config WIFI_CMD_NETWORK_SSID
|
||||
string "WiFi SSID"
|
||||
default "myssid"
|
||||
help
|
||||
SSID (network name) to connect to.
|
||||
|
||||
config WIFI_CMD_NETWORK_PASSWORD
|
||||
string "WiFi Password"
|
||||
default "mypassword"
|
||||
help
|
||||
WiFi password (WPA or WPA2) to use.
|
||||
Can be left blank if the network has no security set.
|
||||
|
||||
endmenu
|
@ -33,12 +33,16 @@ The component offers a console with a command that enables runtime wifi configur
|
||||
ESP_ERROR_CHECK(console_cmd_start()); // Start console
|
||||
```
|
||||
|
||||
Note: Auto-registration of a specific plugin command can be disabled from menuconfig.
|
||||
|
||||
## Suported command:
|
||||
|
||||
### wifi:
|
||||
* ```wifi help```: Prints the help text for all wifi commands
|
||||
* ```wifi show network```: Scans and displays upto 10 available wifi networks.
|
||||
* ```wifi show sta```: Shows the details of wifi station.
|
||||
* ```wifi sta join <network ssid> <password>```: Station joins the given wifi network.
|
||||
* ```wifi sta join <network ssid>```: Station joins the given unsecured wifi network.
|
||||
* ```wifi sta leave```: Station leaves the wifi network.
|
||||
```
|
||||
wifi help: Prints the help text for all wifi commands
|
||||
wifi show network/sta: Scans and displays all available wifi APs./ Shows the details of wifi station.
|
||||
wifi sta join <network ssid> <password>: Station joins the given wifi network.
|
||||
wifi sta join <network ssid>: Station joins the given unsecured wifi network.
|
||||
wifi sta join: Station joins the pre-configured wifi network.
|
||||
wifi sta leave: Station leaves the wifi network.
|
||||
```
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#define DEFAULT_SCAN_LIST_SIZE 10
|
||||
|
||||
#if CONFIG_WIFI_CMD_AUTO_REGISTRATION
|
||||
/**
|
||||
* Static registration of this plugin is achieved by defining the plugin description
|
||||
* structure and placing it into .console_cmd_desc section.
|
||||
@ -30,6 +31,7 @@ static const console_cmd_plugin_desc_t __attribute__((section(".console_cmd_desc
|
||||
.name = "console_cmd_wifi",
|
||||
.plugin_regd_fn = &console_cmd_wifi_register
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct wifi_op_t {
|
||||
char *name;
|
||||
@ -55,8 +57,9 @@ static const int CONNECTED_BIT = BIT1;
|
||||
static wifi_op_t cmd_list[] = {
|
||||
{.name = "help", .operation = wifi_help_op, .arg_cnt = 2, .start_index = 1, .help = "wifi help: Prints the help text for all wifi commands"},
|
||||
{.name = "show", .operation = wifi_show_op, .arg_cnt = 3, .start_index = 1, .help = "wifi show network/sta: Scans and displays all available wifi APs./ Shows the details of wifi station."},
|
||||
{.name = "join", .operation = wifi_sta_join_op, .arg_cnt = 4, .start_index = 2, .help = "wifi sta join <network ssid> <password>: Station joins the given wifi network."},
|
||||
{.name = "join", .operation = wifi_sta_join_op, .arg_cnt = 5, .start_index = 2, .help = "wifi sta join <network ssid>: Station joins the given unsecured wifi network."},
|
||||
{.name = "join", .operation = wifi_sta_join_op, .arg_cnt = 5, .start_index = 2, .help = "wifi sta join <network ssid> <password>: Station joins the given wifi network."},
|
||||
{.name = "join", .operation = wifi_sta_join_op, .arg_cnt = 4, .start_index = 2, .help = "wifi sta join <network ssid>: Station joins the given unsecured wifi network."},
|
||||
{.name = "join", .operation = wifi_sta_join_op, .arg_cnt = 3, .start_index = 2, .help = "wifi sta join: Station joins the pre-configured wifi network."},
|
||||
{.name = "leave", .operation = wifi_sta_leave_op, .arg_cnt = 3, .start_index = 2, .help = "wifi sta leave: Station leaves the wifi network."},
|
||||
};
|
||||
|
||||
@ -162,7 +165,6 @@ static esp_err_t wifi_show_op(wifi_op_t *self, int argc, char *argv[])
|
||||
ESP_LOGI(TAG, "Showing Joind AP details:");
|
||||
ESP_LOGI(TAG, "*************************");
|
||||
ESP_LOGI(TAG, "SSID: %s", wifi_config.sta.ssid);
|
||||
ESP_LOGI(TAG, "Password: %s", wifi_config.sta.password);
|
||||
ESP_LOGI(TAG, "Channel: %d", wifi_config.sta.channel);
|
||||
ESP_LOGI(TAG, "bssid: %02x:%02x:%02x:%02x:%02x:%02x", wifi_config.sta.bssid[0],
|
||||
wifi_config.sta.bssid[1], wifi_config.sta.bssid[2], wifi_config.sta.bssid[3],
|
||||
@ -184,7 +186,13 @@ static esp_err_t wifi_sta_join_op(wifi_op_t *self, int argc, char *argv[])
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
strlcpy((char *) wifi_config.sta.ssid, argv[self->start_index + 1], sizeof(wifi_config.sta.ssid));
|
||||
if (self->arg_cnt == 3) {
|
||||
strlcpy((char *) wifi_config.sta.ssid, CONFIG_WIFI_CMD_NETWORK_SSID, sizeof(wifi_config.sta.ssid));
|
||||
strlcpy((char *) wifi_config.sta.password, CONFIG_WIFI_CMD_NETWORK_PASSWORD, sizeof(wifi_config.sta.password));
|
||||
} else {
|
||||
strlcpy((char *) wifi_config.sta.ssid, argv[self->start_index + 1], sizeof(wifi_config.sta.ssid));
|
||||
}
|
||||
|
||||
if (self->arg_cnt == 5) {
|
||||
strlcpy((char *) wifi_config.sta.password, argv[self->start_index + 2], sizeof(wifi_config.sta.password));
|
||||
}
|
||||
@ -260,7 +268,7 @@ static esp_err_t do_cmd_wifi(int argc, char **argv)
|
||||
*/
|
||||
esp_err_t console_cmd_wifi_register(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_console_cmd_t command = {
|
||||
.command = "wifi",
|
||||
.help = "Command for wifi configuration and monitoring\n For more info run 'wifi help'",
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 1.0.1
|
||||
version: 1.1.0
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/console_cmd_wifi
|
||||
description: The component offers a console that enables runtime wifi configuration and monitoring.
|
||||
dependencies:
|
||||
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(eppp): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py eppp_link
|
||||
tag_format: eppp-v$version
|
||||
version: 0.1.0
|
||||
version: 0.2.0
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,22 @@
|
||||
# Changelog
|
||||
|
||||
## [0.2.0](https://github.com/espressif/esp-protocols/commits/eppp-v0.2.0)
|
||||
|
||||
### Features
|
||||
|
||||
- Add support for SDIO transport ([085dd790](https://github.com/espressif/esp-protocols/commit/085dd790))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed strict prototype API decl issue in SDIO ([eb09e426](https://github.com/espressif/esp-protocols/commit/eb09e426))
|
||||
- Fix SIDO host to check/clear interrupts atomically ([402176c9](https://github.com/espressif/esp-protocols/commit/402176c9))
|
||||
|
||||
## [0.1.1](https://github.com/espressif/esp-protocols/commits/eppp-v0.1.1)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Make some common netif options configurable ([7829e8f](https://github.com/espressif/esp-protocols/commit/7829e8f))
|
||||
|
||||
## [0.1.0](https://github.com/espressif/esp-protocols/commits/eppp-v0.1.0)
|
||||
|
||||
### Features
|
||||
|
@ -1,3 +1,3 @@
|
||||
idf_component_register(SRCS "eppp_link.c"
|
||||
idf_component_register(SRCS eppp_link.c eppp_sdio_slave.c eppp_sdio_host.c
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_REQUIRES esp_netif esp_driver_spi esp_driver_gpio esp_timer driver)
|
||||
|
@ -21,6 +21,13 @@ menu "eppp_link"
|
||||
bool "SPI"
|
||||
help
|
||||
Use SPI.
|
||||
|
||||
config EPPP_LINK_DEVICE_SDIO
|
||||
bool "SDIO"
|
||||
depends on SOC_SDMMC_HOST_SUPPORTED || SOC_SDIO_SLAVE_SUPPORTED
|
||||
help
|
||||
Use SDIO.
|
||||
|
||||
endchoice
|
||||
|
||||
config EPPP_LINK_CONN_MAX_RETRY
|
||||
@ -34,8 +41,30 @@ menu "eppp_link"
|
||||
config EPPP_LINK_PACKET_QUEUE_SIZE
|
||||
int "Packet queue size"
|
||||
default 64
|
||||
depends on EPPP_LINK_DEVICE_SPI
|
||||
help
|
||||
Size of the Tx packet queue.
|
||||
You can decrease the number for slower bit rates.
|
||||
|
||||
choice EPPP_LINK_SDIO_ROLE
|
||||
prompt "Choose SDIO host or slave"
|
||||
depends on EPPP_LINK_DEVICE_SDIO
|
||||
default EPPP_LINK_DEVICE_SDIO_HOST if SOC_SDMMC_HOST_SUPPORTED
|
||||
help
|
||||
Select which either SDIO host or slave
|
||||
|
||||
config EPPP_LINK_DEVICE_SDIO_HOST
|
||||
bool "Host"
|
||||
depends on SOC_SDMMC_HOST_SUPPORTED
|
||||
help
|
||||
Use SDIO host.
|
||||
|
||||
config EPPP_LINK_DEVICE_SDIO_SLAVE
|
||||
bool "SLAVE"
|
||||
depends on SOC_SDIO_SLAVE_SUPPORTED
|
||||
help
|
||||
Use SDIO slave.
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
@ -14,7 +14,7 @@ brings in the WiFi connectivity from the "SLAVE" microcontroller.
|
||||
SLAVE micro HOST micro
|
||||
\|/ +----------------+ +----------------+
|
||||
| | | serial line | |
|
||||
+---+ WiFi NAT PPPoS |======== UART / SPI =======| PPPoS client |
|
||||
+---+ WiFi NAT PPPoS |=== UART / SPI / SDIO =====| PPPoS client |
|
||||
| (server)| | |
|
||||
+----------------+ +----------------+
|
||||
```
|
||||
@ -39,14 +39,19 @@ brings in the WiFi connectivity from the "SLAVE" microcontroller.
|
||||
|
||||
## Throughput
|
||||
|
||||
Tested with WiFi-NAPT example, no IRAM optimizations
|
||||
Tested with WiFi-NAPT example
|
||||
|
||||
### UART @ 3Mbauds
|
||||
|
||||
* TCP - 2Mbits/s
|
||||
* UDP - 2Mbits/s
|
||||
|
||||
### SPI @ 20MHz
|
||||
### SPI @ 16MHz
|
||||
|
||||
* TCP - 6Mbits/s
|
||||
* UDP - 10Mbits/s
|
||||
* TCP - 5Mbits/s
|
||||
* UDP - 8Mbits/s
|
||||
|
||||
### SDIO
|
||||
|
||||
* TCP - 9Mbits/s
|
||||
* UDP - 11Mbits/s
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "esp_event.h"
|
||||
#include "esp_netif_ppp.h"
|
||||
#include "eppp_link.h"
|
||||
#include "esp_serial_slave_link/essl_sdio.h"
|
||||
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SPI
|
||||
#include "driver/spi_master.h"
|
||||
@ -86,7 +87,18 @@ struct eppp_handle {
|
||||
bool netif_stop;
|
||||
};
|
||||
|
||||
typedef esp_err_t (*transmit_t)(void *h, void *buffer, size_t len);
|
||||
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SDIO
|
||||
esp_err_t eppp_sdio_host_tx(void *h, void *buffer, size_t len);
|
||||
esp_err_t eppp_sdio_host_rx(esp_netif_t *netif);
|
||||
esp_err_t eppp_sdio_slave_rx(esp_netif_t *netif);
|
||||
esp_err_t eppp_sdio_slave_tx(void *h, void *buffer, size_t len);
|
||||
esp_err_t eppp_sdio_host_init(struct eppp_config_sdio_s *config);
|
||||
esp_err_t eppp_sdio_slave_init(void);
|
||||
void eppp_sdio_slave_deinit(void);
|
||||
void eppp_sdio_host_deinit(void);
|
||||
#else
|
||||
static esp_err_t transmit(void *h, void *buffer, size_t len)
|
||||
{
|
||||
struct eppp_handle *handle = h;
|
||||
@ -125,9 +137,10 @@ static esp_err_t transmit(void *h, void *buffer, size_t len)
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_UART
|
||||
ESP_LOG_BUFFER_HEXDUMP("ppp_uart_send", buffer, len, ESP_LOG_VERBOSE);
|
||||
uart_write_bytes(handle->uart_port, buffer, len);
|
||||
#endif
|
||||
#endif // DEVICE UART or SPI
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void netif_deinit(esp_netif_t *netif)
|
||||
{
|
||||
@ -157,7 +170,7 @@ static void netif_deinit(esp_netif_t *netif)
|
||||
}
|
||||
}
|
||||
|
||||
static esp_netif_t *netif_init(eppp_type_t role)
|
||||
static esp_netif_t *netif_init(eppp_type_t role, eppp_config_t *eppp_config)
|
||||
{
|
||||
if (s_eppp_netif_count > 9) { // Limit to max 10 netifs, since we use "EPPPx" as the unique key (where x is 0-9)
|
||||
ESP_LOGE(TAG, "Cannot create more than 10 instances");
|
||||
@ -209,7 +222,11 @@ static esp_netif_t *netif_init(eppp_type_t role)
|
||||
|
||||
esp_netif_driver_ifconfig_t driver_cfg = {
|
||||
.handle = h,
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SDIO
|
||||
.transmit = role == EPPP_CLIENT ? eppp_sdio_host_tx : eppp_sdio_slave_tx,
|
||||
#else
|
||||
.transmit = transmit,
|
||||
#endif
|
||||
};
|
||||
const esp_netif_driver_ifconfig_t *ppp_driver_cfg = &driver_cfg;
|
||||
|
||||
@ -217,10 +234,13 @@ static esp_netif_t *netif_init(eppp_type_t role)
|
||||
char if_key[] = "EPPP0"; // netif key needs to be unique
|
||||
if_key[sizeof(if_key) - 2 /* 2 = two chars before the terminator */ ] += s_eppp_netif_count++;
|
||||
base_netif_cfg.if_key = if_key;
|
||||
if (role == EPPP_CLIENT) {
|
||||
base_netif_cfg.if_desc = "pppos_client";
|
||||
if (eppp_config->ppp.netif_description) {
|
||||
base_netif_cfg.if_desc = eppp_config->ppp.netif_description;
|
||||
} else {
|
||||
base_netif_cfg.if_desc = "pppos_server";
|
||||
base_netif_cfg.if_desc = role == EPPP_CLIENT ? "pppos_client" : "pppos_server";
|
||||
}
|
||||
if (eppp_config->ppp.netif_prio) {
|
||||
base_netif_cfg.route_prio = eppp_config->ppp.netif_prio;
|
||||
}
|
||||
esp_netif_config_t netif_ppp_config = { .base = &base_netif_cfg,
|
||||
.driver = ppp_driver_cfg,
|
||||
@ -654,6 +674,20 @@ esp_err_t eppp_perform(esp_netif_t *netif)
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_SDIO
|
||||
|
||||
esp_err_t eppp_perform(esp_netif_t *netif)
|
||||
{
|
||||
struct eppp_handle *h = esp_netif_get_io_driver(netif);
|
||||
if (h->stop) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
if (h->role == EPPP_SERVER) {
|
||||
return eppp_sdio_slave_rx(netif);
|
||||
} else {
|
||||
return eppp_sdio_host_rx(netif);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONFIG_EPPP_LINK_DEVICE_SPI / UART
|
||||
|
||||
@ -697,16 +731,27 @@ void eppp_deinit(esp_netif_t *netif)
|
||||
}
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_UART
|
||||
deinit_uart(esp_netif_get_io_driver(netif));
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_SDIO
|
||||
struct eppp_handle *h = esp_netif_get_io_driver(netif);
|
||||
if (h->role == EPPP_CLIENT) {
|
||||
eppp_sdio_host_deinit();
|
||||
} else {
|
||||
eppp_sdio_slave_deinit();
|
||||
}
|
||||
#endif
|
||||
netif_deinit(netif);
|
||||
}
|
||||
|
||||
esp_netif_t *eppp_init(eppp_type_t role, eppp_config_t *config)
|
||||
{
|
||||
esp_netif_t *netif = netif_init(role);
|
||||
if (config == NULL || (role != EPPP_SERVER && role != EPPP_CLIENT)) {
|
||||
ESP_LOGE(TAG, "Invalid configuration or role");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_netif_t *netif = netif_init(role, config);
|
||||
if (!netif) {
|
||||
ESP_LOGE(TAG, "Failed to initialize PPP netif");
|
||||
remove_handlers();
|
||||
return NULL;
|
||||
}
|
||||
esp_netif_ppp_config_t netif_params;
|
||||
@ -724,12 +769,28 @@ esp_netif_t *eppp_init(eppp_type_t role, eppp_config_t *config)
|
||||
}
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_UART
|
||||
init_uart(esp_netif_get_io_driver(netif), config);
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_SDIO
|
||||
esp_err_t ret;
|
||||
if (role == EPPP_SERVER) {
|
||||
ret = eppp_sdio_slave_init();
|
||||
} else {
|
||||
ret = eppp_sdio_host_init(&config->sdio);
|
||||
}
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to initialize SDIO %d", ret);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return netif;
|
||||
}
|
||||
|
||||
esp_netif_t *eppp_open(eppp_type_t role, eppp_config_t *config, int connect_timeout_ms)
|
||||
{
|
||||
if (config == NULL || (role != EPPP_SERVER && role != EPPP_CLIENT)) {
|
||||
ESP_LOGE(TAG, "Invalid configuration or role");
|
||||
return NULL;
|
||||
}
|
||||
#if CONFIG_EPPP_LINK_DEVICE_UART
|
||||
if (config->transport != EPPP_TRANSPORT_UART) {
|
||||
ESP_LOGE(TAG, "Invalid transport: UART device must be enabled in Kconfig");
|
||||
@ -742,6 +803,12 @@ esp_netif_t *eppp_open(eppp_type_t role, eppp_config_t *config, int connect_time
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SDIO
|
||||
if (config->transport != EPPP_TRANSPORT_SDIO) {
|
||||
ESP_LOGE(TAG, "Invalid transport: SDIO device must be enabled in Kconfig");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (config->task.run_task == false) {
|
||||
ESP_LOGE(TAG, "task.run_task == false is invalid in this API. Please use eppp_init()");
|
||||
|
19
components/eppp_link/eppp_sdio.h
Normal file
19
components/eppp_link/eppp_sdio.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define MAX_SDIO_PAYLOAD 1500
|
||||
#define SDIO_ALIGN(size) (((size) + 3U) & ~(3U))
|
||||
#define SDIO_PAYLOAD SDIO_ALIGN(MAX_SDIO_PAYLOAD)
|
||||
#define PPP_SOF 0x7E
|
||||
|
||||
// Interrupts and registers
|
||||
#define SLAVE_INTR 0
|
||||
#define SLAVE_REG_REQ 0
|
||||
|
||||
// Requests from host to slave
|
||||
#define REQ_RESET 1
|
||||
#define REQ_INIT 2
|
200
components/eppp_link/eppp_sdio_host.c
Normal file
200
components/eppp_link/eppp_sdio_host.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "driver/sdio_slave.h"
|
||||
#include "esp_serial_slave_link/essl_sdio.h"
|
||||
#include "eppp_sdio.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "esp_check.h"
|
||||
#include "eppp_link.h"
|
||||
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SDIO_HOST
|
||||
|
||||
// For blocking operations
|
||||
#define TIMEOUT_MAX UINT32_MAX
|
||||
// Short timeout for sending/receiving ESSL packets
|
||||
#define PACKET_TIMEOUT_MS 50
|
||||
|
||||
static const char *TAG = "eppp_sdio_host";
|
||||
static SemaphoreHandle_t s_essl_mutex = NULL;
|
||||
static essl_handle_t s_essl = NULL;
|
||||
static sdmmc_card_t *s_card = NULL;
|
||||
|
||||
static DRAM_DMA_ALIGNED_ATTR uint8_t send_buffer[SDIO_PAYLOAD];
|
||||
static DMA_ATTR uint8_t rcv_buffer[SDIO_PAYLOAD];
|
||||
|
||||
esp_err_t eppp_sdio_host_tx(void *h, void *buffer, size_t len)
|
||||
{
|
||||
if (s_essl == NULL || s_essl_mutex == NULL) {
|
||||
// silently skip the Tx if the SDIO not fully initialized
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
memcpy(send_buffer, buffer, len);
|
||||
size_t send_len = SDIO_ALIGN(len);
|
||||
if (send_len > len) {
|
||||
// pad with SOF's
|
||||
memset(&send_buffer[len], PPP_SOF, send_len - len);
|
||||
}
|
||||
xSemaphoreTake(s_essl_mutex, portMAX_DELAY);
|
||||
esp_err_t ret = essl_send_packet(s_essl, send_buffer, send_len, PACKET_TIMEOUT_MS);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Slave not ready to receive packet %x", ret);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
ret = ESP_ERR_NO_MEM; // to inform the upper layers
|
||||
}
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, send_buffer, send_len, ESP_LOG_VERBOSE);
|
||||
xSemaphoreGive(s_essl_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t request_slave_reset(void)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_LOGI(TAG, "send reset to slave...");
|
||||
ESP_GOTO_ON_ERROR(essl_write_reg(s_essl, SLAVE_REG_REQ, REQ_RESET, NULL, TIMEOUT_MAX), err, TAG, "write-reg failed");
|
||||
ESP_GOTO_ON_ERROR(essl_send_slave_intr(s_essl, BIT(SLAVE_INTR), TIMEOUT_MAX), err, TAG, "send-intr failed");
|
||||
vTaskDelay(pdMS_TO_TICKS(PACKET_TIMEOUT_MS));
|
||||
ESP_GOTO_ON_ERROR(essl_wait_for_ready(s_essl, TIMEOUT_MAX), err, TAG, "wait-for-ready failed");
|
||||
ESP_LOGI(TAG, "slave io ready");
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t eppp_sdio_host_init(struct eppp_config_sdio_s *eppp_config)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
ESP_GOTO_ON_ERROR(sdmmc_host_init(), err, TAG, "sdmmc host init failed");
|
||||
|
||||
// configure SDIO interface and slot
|
||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||
slot_config.width = eppp_config->width;
|
||||
#ifdef CONFIG_SOC_SDMMC_USE_GPIO_MATRIX
|
||||
slot_config.clk = eppp_config->clk;
|
||||
slot_config.cmd = eppp_config->cmd;
|
||||
slot_config.d0 = eppp_config->d0;
|
||||
slot_config.d1 = eppp_config->d1;
|
||||
slot_config.d2 = eppp_config->d2;
|
||||
slot_config.d3 = eppp_config->d3;
|
||||
#endif
|
||||
|
||||
ESP_GOTO_ON_ERROR(sdmmc_host_init_slot(SDMMC_HOST_SLOT_1, &slot_config), err, TAG, "init sdmmc host slot failed");
|
||||
|
||||
sdmmc_host_t config = SDMMC_HOST_DEFAULT();
|
||||
config.flags = SDMMC_HOST_FLAG_4BIT;
|
||||
config.flags |= SDMMC_HOST_FLAG_ALLOC_ALIGNED_BUF;
|
||||
config.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
|
||||
|
||||
s_card = (sdmmc_card_t *)malloc(sizeof(sdmmc_card_t));
|
||||
ESP_GOTO_ON_FALSE(s_card, ESP_ERR_NO_MEM, err, TAG, "card allocation failed");
|
||||
ESP_GOTO_ON_ERROR(sdmmc_card_init(&config, s_card), err, TAG, "sdmmc card init failed");
|
||||
|
||||
essl_sdio_config_t ser_config = {
|
||||
.card = s_card,
|
||||
.recv_buffer_size = SDIO_PAYLOAD,
|
||||
};
|
||||
ESP_GOTO_ON_FALSE(essl_sdio_init_dev(&s_essl, &ser_config) == ESP_OK && s_essl, ESP_FAIL, err, TAG, "essl_sdio_init_dev failed");
|
||||
ESP_GOTO_ON_ERROR(essl_init(s_essl, TIMEOUT_MAX), err, TAG, "essl-init failed");
|
||||
ESP_GOTO_ON_ERROR(request_slave_reset(), err, TAG, "failed to reset the slave");
|
||||
ESP_GOTO_ON_FALSE((s_essl_mutex = xSemaphoreCreateMutex()), ESP_ERR_NO_MEM, err, TAG, "failed to create semaphore");
|
||||
return ret;
|
||||
|
||||
err:
|
||||
essl_sdio_deinit_dev(s_essl);
|
||||
s_essl = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t get_intr(uint32_t *out_raw)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_GOTO_ON_ERROR(essl_get_intr(s_essl, out_raw, NULL, 0), err, TAG, "essl-get-int failed");
|
||||
ESP_GOTO_ON_ERROR(essl_clear_intr(s_essl, *out_raw, 0), err, TAG, "essl-clear-int failed");
|
||||
ESP_LOGD(TAG, "intr: %08"PRIX32, *out_raw);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t eppp_sdio_host_rx(esp_netif_t *netif)
|
||||
{
|
||||
uint32_t intr;
|
||||
esp_err_t err = essl_wait_int(s_essl, TIMEOUT_MAX);
|
||||
if (err == ESP_ERR_TIMEOUT) {
|
||||
return ESP_OK;
|
||||
}
|
||||
xSemaphoreTake(s_essl_mutex, portMAX_DELAY);
|
||||
err = get_intr(&intr);
|
||||
if (err == ESP_ERR_TIMEOUT) {
|
||||
xSemaphoreGive(s_essl_mutex);
|
||||
return ESP_OK;
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to check for interrupts %d", err);
|
||||
xSemaphoreGive(s_essl_mutex);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (intr & ESSL_SDIO_DEF_ESP32.new_packet_intr_mask) {
|
||||
esp_err_t ret;
|
||||
do {
|
||||
size_t size_read = SDIO_PAYLOAD;
|
||||
ret = essl_get_packet(s_essl, rcv_buffer, SDIO_PAYLOAD, &size_read, PACKET_TIMEOUT_MS);
|
||||
if (ret == ESP_ERR_NOT_FOUND) {
|
||||
ESP_LOGE(TAG, "interrupt but no data can be read");
|
||||
break;
|
||||
} else if (ret == ESP_OK) {
|
||||
ESP_LOGD(TAG, "receive data, size: %d", size_read);
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, rcv_buffer, size_read, ESP_LOG_VERBOSE);
|
||||
esp_netif_receive(netif, rcv_buffer, size_read, NULL);
|
||||
break;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "rx packet error: %08X", ret);
|
||||
if (request_slave_reset() != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to request slave reset %x", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (ret == ESP_ERR_NOT_FINISHED);
|
||||
}
|
||||
xSemaphoreGive(s_essl_mutex);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void eppp_sdio_host_deinit(void)
|
||||
{
|
||||
essl_sdio_deinit_dev(s_essl);
|
||||
sdmmc_host_deinit();
|
||||
free(s_card);
|
||||
s_card = NULL;
|
||||
s_essl = NULL;
|
||||
}
|
||||
|
||||
#else // SDMMC_HOST NOT-SUPPORTED
|
||||
|
||||
esp_err_t eppp_sdio_host_tx(void *handle, void *buffer, size_t len)
|
||||
{
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_err_t eppp_sdio_host_rx(esp_netif_t *netif)
|
||||
{
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void eppp_sdio_host_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
esp_err_t eppp_sdio_host_init(struct eppp_config_sdio_s *config)
|
||||
{
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif // CONFIG_SOC_SDIO_SLAVE_SUPPORTED
|
174
components/eppp_link/eppp_sdio_slave.c
Normal file
174
components/eppp_link/eppp_sdio_slave.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "driver/sdio_slave.h"
|
||||
#include "eppp_sdio.h"
|
||||
#include "esp_check.h"
|
||||
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SDIO_SLAVE
|
||||
#define BUFFER_NUM 4
|
||||
#define BUFFER_SIZE SDIO_PAYLOAD
|
||||
static const char *TAG = "eppp_sdio_slave";
|
||||
static DMA_ATTR uint8_t sdio_slave_rx_buffer[BUFFER_NUM][BUFFER_SIZE];
|
||||
static DMA_ATTR uint8_t sdio_slave_tx_buffer[SDIO_PAYLOAD];
|
||||
static int s_slave_request = 0;
|
||||
|
||||
esp_err_t eppp_sdio_slave_tx(void *h, void *buffer, size_t len)
|
||||
{
|
||||
if (s_slave_request != REQ_INIT) {
|
||||
// silently skip the Tx if the SDIO not fully initialized
|
||||
return ESP_OK;
|
||||
}
|
||||
memcpy(sdio_slave_tx_buffer, buffer, len);
|
||||
size_t send_len = SDIO_ALIGN(len);
|
||||
if (send_len > len) {
|
||||
// pad with SOF's if the size is not 4 bytes aligned
|
||||
memset(&sdio_slave_tx_buffer[len], PPP_SOF, send_len - len);
|
||||
}
|
||||
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, sdio_slave_tx_buffer, send_len, ESP_LOG_VERBOSE);
|
||||
esp_err_t ret = sdio_slave_transmit(sdio_slave_tx_buffer, send_len);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "sdio slave transmit error, ret : 0x%x", ret);
|
||||
// to inform the upper layers
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t slave_reset(void)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_LOGI(TAG, "SDIO slave reset");
|
||||
sdio_slave_stop();
|
||||
ESP_GOTO_ON_ERROR(sdio_slave_reset(), err, TAG, "slave reset failed");
|
||||
ESP_GOTO_ON_ERROR(sdio_slave_start(), err, TAG, "slave start failed");
|
||||
|
||||
while (1) {
|
||||
sdio_slave_buf_handle_t handle;
|
||||
ret = sdio_slave_send_get_finished(&handle, 0);
|
||||
if (ret == ESP_ERR_TIMEOUT) {
|
||||
break;
|
||||
}
|
||||
ESP_GOTO_ON_ERROR(ret, err, TAG, "slave-get-finished failed");
|
||||
ESP_GOTO_ON_ERROR(sdio_slave_recv_load_buf(handle), err, TAG, "slave-load-buf failed");
|
||||
}
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t eppp_sdio_slave_rx(esp_netif_t *netif)
|
||||
{
|
||||
if (s_slave_request == REQ_RESET) {
|
||||
ESP_LOGD(TAG, "request: %x", s_slave_request);
|
||||
slave_reset();
|
||||
s_slave_request = REQ_INIT;
|
||||
}
|
||||
sdio_slave_buf_handle_t handle;
|
||||
size_t length;
|
||||
uint8_t *ptr;
|
||||
esp_err_t ret = sdio_slave_recv_packet(&handle, pdMS_TO_TICKS(1000));
|
||||
if (ret == ESP_ERR_TIMEOUT) {
|
||||
return ESP_OK;
|
||||
}
|
||||
if (ret == ESP_ERR_NOT_FINISHED || ret == ESP_OK) {
|
||||
again:
|
||||
ptr = sdio_slave_recv_get_buf(handle, &length);
|
||||
esp_netif_receive(netif, ptr, length, NULL);
|
||||
if (sdio_slave_recv_load_buf(handle) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to recycle packet buffer");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (ret == ESP_ERR_NOT_FINISHED) {
|
||||
ret = sdio_slave_recv_packet(&handle, 0);
|
||||
if (ret == ESP_ERR_NOT_FINISHED || ret == ESP_OK) {
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, length, ESP_LOG_VERBOSE);
|
||||
return ESP_OK;
|
||||
}
|
||||
ESP_LOGE(TAG, "Error when receiving packet %d", ret);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
static void event_cb(uint8_t pos)
|
||||
{
|
||||
ESP_EARLY_LOGI(TAG, "SDIO event: %d", pos);
|
||||
if (pos == SLAVE_INTR) {
|
||||
s_slave_request = sdio_slave_read_reg(SLAVE_REG_REQ);
|
||||
sdio_slave_write_reg(SLAVE_REG_REQ, 0);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t eppp_sdio_slave_init(void)
|
||||
{
|
||||
sdio_slave_config_t config = {
|
||||
.sending_mode = SDIO_SLAVE_SEND_PACKET,
|
||||
.send_queue_size = BUFFER_NUM,
|
||||
.recv_buffer_size = BUFFER_SIZE,
|
||||
.event_cb = event_cb,
|
||||
};
|
||||
esp_err_t ret = sdio_slave_initialize(&config);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (int i = 0; i < BUFFER_NUM; i++) {
|
||||
sdio_slave_buf_handle_t handle = sdio_slave_recv_register_buf(sdio_slave_rx_buffer[i]);
|
||||
if (handle == NULL) {
|
||||
sdio_slave_deinit();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ret = sdio_slave_recv_load_buf(handle);
|
||||
if (ret != ESP_OK) {
|
||||
sdio_slave_deinit();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
sdio_slave_set_host_intena(SDIO_SLAVE_HOSTINT_SEND_NEW_PACKET); // only need one interrupt to notify of a new packet
|
||||
|
||||
ret = sdio_slave_start();
|
||||
if (ret != ESP_OK) {
|
||||
sdio_slave_deinit();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void eppp_sdio_slave_deinit(void)
|
||||
{
|
||||
sdio_slave_stop();
|
||||
sdio_slave_deinit();
|
||||
}
|
||||
|
||||
#else // SOC_SDIO_SLAVE NOT-SUPPORTED
|
||||
|
||||
esp_err_t eppp_sdio_slave_tx(void *h, void *buffer, size_t len)
|
||||
{
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
esp_err_t eppp_sdio_slave_rx(esp_netif_t *netif)
|
||||
{
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void eppp_sdio_slave_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
esp_err_t eppp_sdio_slave_init(void)
|
||||
{
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
#endif // CONFIG_SOC_SDIO_SLAVE_SUPPORTED
|
@ -104,11 +104,13 @@ void app_main(void)
|
||||
eppp_config_t config = EPPP_DEFAULT_CLIENT_CONFIG();
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SPI
|
||||
config.transport = EPPP_TRANSPORT_SPI;
|
||||
#else
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_UART
|
||||
config.transport = EPPP_TRANSPORT_UART;
|
||||
config.uart.tx_io = CONFIG_EXAMPLE_UART_TX_PIN;
|
||||
config.uart.rx_io = CONFIG_EXAMPLE_UART_RX_PIN;
|
||||
config.uart.baud = CONFIG_EXAMPLE_UART_BAUDRATE;
|
||||
#else
|
||||
config.transport = EPPP_TRANSPORT_SDIO;
|
||||
#endif
|
||||
esp_netif_t *eppp_netif = eppp_connect(&config);
|
||||
if (eppp_netif == NULL) {
|
||||
|
@ -128,16 +128,21 @@ void app_main(void)
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
init_network_interface(); // WiFi station if withing SoC capabilities (otherwise a placeholder)
|
||||
// ESP_ERROR_CHECK(esp_netif_init());
|
||||
// ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
eppp_config_t config = EPPP_DEFAULT_SERVER_CONFIG();
|
||||
#if CONFIG_EPPP_LINK_DEVICE_SPI
|
||||
config.transport = EPPP_TRANSPORT_SPI;
|
||||
#else
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_UART
|
||||
config.transport = EPPP_TRANSPORT_UART;
|
||||
config.uart.tx_io = CONFIG_EXAMPLE_UART_TX_PIN;
|
||||
config.uart.rx_io = CONFIG_EXAMPLE_UART_RX_PIN;
|
||||
config.uart.baud = CONFIG_EXAMPLE_UART_BAUDRATE;
|
||||
#endif
|
||||
#elif CONFIG_EPPP_LINK_DEVICE_SDIO
|
||||
config.transport = EPPP_TRANSPORT_SDIO;
|
||||
#endif // transport device
|
||||
|
||||
esp_netif_t *eppp_netif = eppp_listen(&config);
|
||||
if (eppp_netif == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to setup connection");
|
||||
|
@ -1,6 +1,6 @@
|
||||
version: 0.1.0
|
||||
version: 0.2.0
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/eppp_link
|
||||
description: The component provides a general purpose PPP connectivity, typically used as WiFi-PPP router
|
||||
dependencies:
|
||||
idf:
|
||||
version: '>=5.2'
|
||||
idf: '>=5.2'
|
||||
espressif/esp_serial_slave_link: "^1.1.0"
|
||||
|
@ -28,7 +28,16 @@
|
||||
.rx_io = 26, \
|
||||
.queue_size = 16, \
|
||||
.rx_buffer_size = 1024, \
|
||||
}, \
|
||||
}, \
|
||||
.sdio = { \
|
||||
.width = 4, \
|
||||
.clk = 18, \
|
||||
.cmd = 19, \
|
||||
.d0 = 49, \
|
||||
.d1 = 50, \
|
||||
.d2 = 16, \
|
||||
.d3 = 17, \
|
||||
}, \
|
||||
. task = { \
|
||||
.run_task = true, \
|
||||
.stack_size = 4096, \
|
||||
@ -37,6 +46,8 @@
|
||||
. ppp = { \
|
||||
.our_ip4_addr = { .addr = our_ip }, \
|
||||
.their_ip4_addr = { .addr = their_ip }, \
|
||||
.netif_prio = 0, \
|
||||
.netif_description = NULL, \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -51,6 +62,7 @@ typedef enum eppp_type {
|
||||
typedef enum eppp_transport {
|
||||
EPPP_TRANSPORT_UART,
|
||||
EPPP_TRANSPORT_SPI,
|
||||
EPPP_TRANSPORT_SDIO,
|
||||
} eppp_transport_t;
|
||||
|
||||
|
||||
@ -79,6 +91,16 @@ typedef struct eppp_config_t {
|
||||
int rx_buffer_size;
|
||||
} uart;
|
||||
|
||||
struct eppp_config_sdio_s {
|
||||
int width;
|
||||
int clk;
|
||||
int cmd;
|
||||
int d0;
|
||||
int d1;
|
||||
int d2;
|
||||
int d3;
|
||||
} sdio;
|
||||
|
||||
struct eppp_config_task_s {
|
||||
bool run_task;
|
||||
int stack_size;
|
||||
@ -88,6 +110,8 @@ typedef struct eppp_config_t {
|
||||
struct eppp_config_pppos_s {
|
||||
esp_ip4_addr_t our_ip4_addr;
|
||||
esp_ip4_addr_t their_ip4_addr;
|
||||
int netif_prio;
|
||||
const char *netif_description;
|
||||
} ppp;
|
||||
|
||||
} eppp_config_t;
|
||||
|
@ -16,9 +16,9 @@ class.
|
||||
|
||||
### USB DTE support
|
||||
|
||||
For USB enabled targets (ESP32-S2 and ESP32-S3), it is possible to connect to the modem device via USB.
|
||||
For USB enabled targets (ESP32-S2, ESP32-S3, or ESP32-P4), it is possible to connect to the modem device via USB.
|
||||
1. In menuconfig, navigate to `Example Configuration->Type of serial connection to the modem` and choose `USB`.
|
||||
2. Connect the modem USB signals to pin 19 (DATA-) and 20 (DATA+) on your ESP chip.
|
||||
2. Connect the modem USB signals to your ESP chip (pin 19 (DATA-) and 20 (DATA+) for ESP32-S2/S3).
|
||||
|
||||
USB example uses Quactel BG96 modem device. BG96 needs a positive pulse on its PWK pin to boot-up.
|
||||
|
||||
|
@ -10,7 +10,7 @@ menu "Example Configuration"
|
||||
Connect to modem via UART.
|
||||
config EXAMPLE_SERIAL_CONFIG_USB
|
||||
bool "USB"
|
||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4
|
||||
help
|
||||
Connect to modem via USB (CDC-ACM class). For IDF version >= 4.4.
|
||||
endchoice
|
||||
@ -36,6 +36,11 @@ menu "Example Configuration"
|
||||
bool "BG96"
|
||||
help
|
||||
Quectel BG96 is a series of LTE Cat M1/Cat NB1/EGPRS module.
|
||||
config EXAMPLE_MODEM_DEVICE_EC20
|
||||
depends on EXAMPLE_SERIAL_CONFIG_USB
|
||||
bool "EC20"
|
||||
help
|
||||
Quectel EC20 is a series of LTE Cat M4 module.
|
||||
config EXAMPLE_MODEM_DEVICE_SIM7000
|
||||
depends on EXAMPLE_SERIAL_CONFIG_UART
|
||||
bool "SIM7000"
|
||||
|
@ -6,7 +6,7 @@ dependencies:
|
||||
version: "^1.0.0"
|
||||
override_path: "../../../"
|
||||
espressif/esp_modem_usb_dte:
|
||||
version: "^1.1.0"
|
||||
version: "^1.2.0"
|
||||
rules:
|
||||
- if: "idf_version >=4.4"
|
||||
- if: "target in [esp32s2, esp32s3]"
|
||||
- if: "target in [esp32s2, esp32s3, esp32p4]"
|
||||
|
@ -160,6 +160,9 @@ extern "C" void app_main(void)
|
||||
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for the BG96 module...");
|
||||
struct esp_modem_usb_term_config usb_config = ESP_MODEM_BG96_USB_CONFIG();
|
||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_EC20 == 1
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for the EC20 module...");
|
||||
struct esp_modem_usb_term_config usb_config = ESP_MODEM_EC20_USB_CONFIG();
|
||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for the SIM7600 module...");
|
||||
struct esp_modem_usb_term_config usb_config = ESP_MODEM_SIM7600_USB_CONFIG();
|
||||
@ -180,7 +183,7 @@ extern "C" void app_main(void)
|
||||
});
|
||||
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
|
||||
std::unique_ptr<DCE> dce = create_BG96_dce(&dce_config, dte, esp_netif);
|
||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1 || CONFIG_EXAMPLE_MODEM_DEVICE_A7670 == 1
|
||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1 || CONFIG_EXAMPLE_MODEM_DEVICE_A7670 == 1 || CONFIG_EXAMPLE_MODEM_DEVICE_EC20 == 1
|
||||
std::unique_ptr<DCE> dce = create_SIM7600_dce(&dce_config, dte, esp_netif);
|
||||
#else
|
||||
#error USB modem not selected
|
||||
|
@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32p4"
|
||||
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y
|
@ -11,9 +11,9 @@ See the README.md file in the upper level `pppos` directory for more information
|
||||
|
||||
### USB DTE support
|
||||
|
||||
For USB enabled targets (ESP32-S2 and ESP32-S3), it is possible to connect to the modem device via USB.
|
||||
For USB enabled targets (ESP32-S2, ESP32-S3, or ESP32-P4), it is possible to connect to the modem device via USB.
|
||||
1. In menuconfig, navigate to `Example Configuration->Type of serial connection to the modem` and choose `USB`.
|
||||
2. Connect the modem USB signals to pin 19 (DATA-) and 20 (DATA+) on your ESP chip.
|
||||
2. Connect the modem USB signals to your ESP chip (pin 19 (DATA-) and 20 (DATA+) for ESP32-S2/S3).
|
||||
|
||||
USB example uses Quactel BG96 modem device. BG96 needs a positive pulse on its PWK pin to boot-up.
|
||||
|
||||
|
@ -9,7 +9,7 @@ menu "Example Configuration"
|
||||
Connect to modem via UART.
|
||||
config EXAMPLE_SERIAL_CONFIG_USB
|
||||
bool "USB"
|
||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4
|
||||
help
|
||||
Connect to modem via USB (CDC-ACM class). For IDF version >= 4.4.
|
||||
endchoice
|
||||
@ -29,6 +29,11 @@ menu "Example Configuration"
|
||||
bool "BG96"
|
||||
help
|
||||
Quectel BG96 is a series of LTE Cat M1/Cat NB1/EGPRS module.
|
||||
config EXAMPLE_MODEM_DEVICE_EC20
|
||||
depends on EXAMPLE_SERIAL_CONFIG_USB
|
||||
bool "EC20"
|
||||
help
|
||||
Quectel EC20 is a series of LTE Cat M4 module.
|
||||
config EXAMPLE_MODEM_DEVICE_SIM7000
|
||||
depends on EXAMPLE_SERIAL_CONFIG_UART
|
||||
bool "SIM7000"
|
||||
|
@ -6,7 +6,7 @@ dependencies:
|
||||
version: "^1.0.0"
|
||||
override_path: "../../../"
|
||||
espressif/esp_modem_usb_dte:
|
||||
version: "^1.1.0"
|
||||
version: "^1.2.0"
|
||||
rules:
|
||||
- if: "idf_version >=4.4"
|
||||
- if: "target in [esp32s2, esp32s3]"
|
||||
- if: "target in [esp32s2, esp32s3, esp32p4]"
|
||||
|
@ -219,6 +219,10 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for the BG96 module...");
|
||||
struct esp_modem_usb_term_config usb_config = ESP_MODEM_BG96_USB_CONFIG();
|
||||
esp_modem_dce_device_t usb_dev_type = ESP_MODEM_DCE_BG96;
|
||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_EC20 == 1
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for the EC20 module...");
|
||||
struct esp_modem_usb_term_config usb_config = ESP_MODEM_EC20_USB_CONFIG();
|
||||
esp_modem_dce_device_t usb_dev_type = ESP_MODEM_DCE_EC20;
|
||||
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for the SIM7600 module...");
|
||||
struct esp_modem_usb_term_config usb_config = ESP_MODEM_SIM7600_USB_CONFIG();
|
||||
|
@ -0,0 +1,2 @@
|
||||
CONFIG_IDF_TARGET="esp32p4"
|
||||
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y
|
@ -142,7 +142,6 @@ private:
|
||||
size_t frame_header_offset;
|
||||
uint8_t *payload_start;
|
||||
size_t total_payload_size;
|
||||
int instance;
|
||||
int sabm_ack;
|
||||
|
||||
/**
|
||||
|
@ -65,7 +65,6 @@ private:
|
||||
static void on_ppp_changed(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||
|
||||
std::shared_ptr<DTE> ppp_dte;
|
||||
esp_netif_t *netif;
|
||||
struct ppp_netif_driver driver {};
|
||||
SignalGroup signal;
|
||||
static const size_t PPP_STARTED = SignalGroup::bit0;
|
||||
|
@ -52,6 +52,7 @@ typedef enum esp_modem_dce_device {
|
||||
ESP_MODEM_DCE_SIM7070,
|
||||
ESP_MODEM_DCE_SIM7000,
|
||||
ESP_MODEM_DCE_BG96,
|
||||
ESP_MODEM_DCE_EC20,
|
||||
ESP_MODEM_DCE_SIM800,
|
||||
ESP_MODEM_DCE_CUSTOM
|
||||
} esp_modem_dce_device_t;
|
||||
|
@ -150,7 +150,7 @@ bool CMux::data_available(uint8_t *data, size_t len)
|
||||
return false;
|
||||
}
|
||||
} else if ((type & FT_UIH) == FT_UIH && dlci == 0) { // notify the internal DISC command
|
||||
if ((len > 0 && (data[0] & 0xE1) == 0xE1) || (data == nullptr)) {
|
||||
if ((data == nullptr) || (len > 0 && (data[0] & 0xE1) == 0xE1)) {
|
||||
// Not a DISC, ignore (MSC frame)
|
||||
return true;
|
||||
}
|
||||
@ -346,6 +346,9 @@ bool CMux::on_cmux_data(uint8_t *data, size_t actual_len)
|
||||
actual_len = term->read(data, buffer.size);
|
||||
#endif
|
||||
}
|
||||
if (data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
ESP_LOG_BUFFER_HEXDUMP("CMUX Received", data, actual_len, ESP_LOG_VERBOSE);
|
||||
CMuxFrame frame = { .ptr = data, .len = actual_len };
|
||||
while (frame.len > 0) {
|
||||
|
@ -69,7 +69,7 @@ void Netif::receive(uint8_t *data, size_t len)
|
||||
}
|
||||
|
||||
Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) :
|
||||
ppp_dte(std::move(e)), netif(ppp_netif)
|
||||
ppp_dte(std::move(e))
|
||||
{
|
||||
driver.base.netif = ppp_netif;
|
||||
driver.ppp = this;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -29,11 +29,15 @@ esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args)
|
||||
|
||||
void Netif::receive(uint8_t *data, size_t len)
|
||||
{
|
||||
esp_netif_receive(netif, data, len);
|
||||
esp_netif_receive(driver.base.netif, data, len);
|
||||
}
|
||||
|
||||
Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) :
|
||||
ppp_dte(std::move(e)), netif(ppp_netif) {}
|
||||
ppp_dte(std::move(e))
|
||||
{
|
||||
driver.base.netif = ppp_netif;
|
||||
driver.ppp = this;
|
||||
}
|
||||
|
||||
void Netif::start()
|
||||
{
|
||||
@ -41,8 +45,8 @@ void Netif::start()
|
||||
receive(data, len);
|
||||
return true;
|
||||
});
|
||||
netif->transmit = esp_modem_dte_transmit;
|
||||
netif->ctx = (void *)this;
|
||||
driver.base.netif->transmit = esp_modem_dte_transmit;
|
||||
driver.base.netif->ctx = (void *)this;
|
||||
signal.set(PPP_STARTED);
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ int FdTerminal::write(uint8_t *data, size_t len)
|
||||
|
||||
FdTerminal::~FdTerminal()
|
||||
{
|
||||
stop();
|
||||
FdTerminal::stop();
|
||||
}
|
||||
|
||||
} // namespace esp_modem
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "uart_resource.hpp"
|
||||
#include "vfs_resource/vfs_create.hpp"
|
||||
|
||||
constexpr const char *TAG = "vfs_uart_creator";
|
||||
[[maybe_unused]] constexpr const char *TAG = "vfs_uart_creator";
|
||||
|
||||
|
||||
struct esp_modem_vfs_resource {
|
||||
|
@ -555,9 +555,29 @@ static int esp_websocket_client_send_with_exact_opcode(esp_websocket_client_hand
|
||||
int wlen = 0, widx = 0;
|
||||
bool contained_fin = opcode & WS_TRANSPORT_OPCODES_FIN;
|
||||
|
||||
if (client == NULL || len < 0 || (data == NULL && len > 0)) {
|
||||
ESP_LOGE(TAG, "Invalid arguments");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!esp_websocket_client_is_connected(client)) {
|
||||
ESP_LOGE(TAG, "Websocket client is not connected");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (client->transport == NULL) {
|
||||
ESP_LOGE(TAG, "Invalid transport");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xSemaphoreTakeRecursive(client->lock, timeout) != pdPASS) {
|
||||
ESP_LOGE(TAG, "Could not lock ws-client within %" PRIu32 " timeout", timeout);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (esp_websocket_new_buf(client, true) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to setup tx buffer");
|
||||
return -1;
|
||||
goto unlock_and_return;
|
||||
}
|
||||
|
||||
while (widx < len || opcode) { // allow for sending "current_opcode" only message with len==0
|
||||
@ -583,14 +603,18 @@ static int esp_websocket_client_send_with_exact_opcode(esp_websocket_client_hand
|
||||
esp_websocket_client_error(client, "esp_transport_write() returned %d, errno=%d", ret, errno);
|
||||
}
|
||||
esp_websocket_client_abort_connection(client, WEBSOCKET_ERROR_TYPE_TCP_TRANSPORT);
|
||||
return ret;
|
||||
goto unlock_and_return;
|
||||
}
|
||||
opcode = 0;
|
||||
widx += wlen;
|
||||
need_write = len - widx;
|
||||
}
|
||||
esp_websocket_free_buf(client, true);
|
||||
return widx;
|
||||
ret = widx;
|
||||
|
||||
unlock_and_return:
|
||||
xSemaphoreGiveRecursive(client->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_websocket_client_handle_t esp_websocket_client_init(const esp_websocket_client_config_t *config)
|
||||
@ -1211,35 +1235,7 @@ int esp_websocket_client_send_fin(esp_websocket_client_handle_t client, TickType
|
||||
|
||||
int esp_websocket_client_send_with_opcode(esp_websocket_client_handle_t client, ws_transport_opcodes_t opcode, const uint8_t *data, int len, TickType_t timeout)
|
||||
{
|
||||
int ret = -1;
|
||||
if (client == NULL || len < 0 || (data == NULL && len > 0)) {
|
||||
ESP_LOGE(TAG, "Invalid arguments");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xSemaphoreTakeRecursive(client->lock, timeout) != pdPASS) {
|
||||
ESP_LOGE(TAG, "Could not lock ws-client within %" PRIu32 " timeout", timeout);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!esp_websocket_client_is_connected(client)) {
|
||||
ESP_LOGE(TAG, "Websocket client is not connected");
|
||||
goto unlock_and_return;
|
||||
}
|
||||
|
||||
if (client->transport == NULL) {
|
||||
ESP_LOGE(TAG, "Invalid transport");
|
||||
goto unlock_and_return;
|
||||
}
|
||||
|
||||
ret = esp_websocket_client_send_with_exact_opcode(client, opcode | WS_TRANSPORT_OPCODES_FIN, data, len, timeout);
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "Failed to send the buffer");
|
||||
goto unlock_and_return;
|
||||
}
|
||||
unlock_and_return:
|
||||
xSemaphoreGiveRecursive(client->lock);
|
||||
return ret;
|
||||
return esp_websocket_client_send_with_exact_opcode(client, opcode | WS_TRANSPORT_OPCODES_FIN, data, len, timeout);
|
||||
}
|
||||
|
||||
bool esp_websocket_client_is_connected(esp_websocket_client_handle_t client)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -96,14 +96,24 @@ static void websocket_app_start(void)
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Sending fragmented message");
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
// Sending text data
|
||||
ESP_LOGI(TAG, "Sending fragmented text message");
|
||||
memset(data, 'a', sizeof(data));
|
||||
esp_websocket_client_send_text_partial(client, data, sizeof(data), portMAX_DELAY);
|
||||
memset(data, 'b', sizeof(data));
|
||||
esp_websocket_client_send_cont_msg(client, data, sizeof(data), portMAX_DELAY);
|
||||
esp_websocket_client_send_fin(client, portMAX_DELAY);
|
||||
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
// Sending binary data
|
||||
ESP_LOGI(TAG, "Sending fragmented binary message");
|
||||
char binary_data[128];
|
||||
memset(binary_data, 0, sizeof(binary_data));
|
||||
esp_websocket_client_send_bin_partial(client, binary_data, sizeof(binary_data), portMAX_DELAY);
|
||||
memset(binary_data, 1, sizeof(binary_data));
|
||||
esp_websocket_client_send_cont_msg(client, binary_data, sizeof(binary_data), portMAX_DELAY);
|
||||
esp_websocket_client_send_fin(client, portMAX_DELAY);
|
||||
|
||||
esp_websocket_client_destroy(client);
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,9 @@ static void websocket_event_handler(void *handler_args, esp_event_base_t base, i
|
||||
case WEBSOCKET_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "WEBSOCKET_EVENT_DATA");
|
||||
ESP_LOGI(TAG, "Received opcode=%d", data->op_code);
|
||||
if (data->op_code == 0x08 && data->data_len == 2) {
|
||||
if (data->op_code == 0x2) { // Opcode 0x2 indicates binary data
|
||||
ESP_LOG_BUFFER_HEX("Received binary data", data->data_ptr, data->data_len);
|
||||
} else if (data->op_code == 0x08 && data->data_len == 2) {
|
||||
ESP_LOGW(TAG, "Received closed message with code=%d", 256 * data->data_ptr[0] + data->data_ptr[1]);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Received=%.*s\n\n", data->data_len, (char *)data->data_ptr);
|
||||
@ -183,13 +185,32 @@ static void websocket_app_start(void)
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Sending fragmented message");
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
// Sending text data
|
||||
ESP_LOGI(TAG, "Sending fragmented text message");
|
||||
memset(data, 'a', sizeof(data));
|
||||
esp_websocket_client_send_text_partial(client, data, sizeof(data), portMAX_DELAY);
|
||||
memset(data, 'b', sizeof(data));
|
||||
esp_websocket_client_send_cont_msg(client, data, sizeof(data), portMAX_DELAY);
|
||||
esp_websocket_client_send_fin(client, portMAX_DELAY);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
|
||||
// Sending binary data
|
||||
ESP_LOGI(TAG, "Sending fragmented binary message");
|
||||
char binary_data[5];
|
||||
memset(binary_data, 0, sizeof(binary_data));
|
||||
esp_websocket_client_send_bin_partial(client, binary_data, sizeof(binary_data), portMAX_DELAY);
|
||||
memset(binary_data, 1, sizeof(binary_data));
|
||||
esp_websocket_client_send_cont_msg(client, binary_data, sizeof(binary_data), portMAX_DELAY);
|
||||
esp_websocket_client_send_fin(client, portMAX_DELAY);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
|
||||
// Sending text data longer than ws buffer (default 1024)
|
||||
ESP_LOGI(TAG, "Sending text longer than ws buffer (default 1024)");
|
||||
const int size = 2000;
|
||||
char *long_data = malloc(size);
|
||||
memset(long_data, 'a', size);
|
||||
esp_websocket_client_send_text(client, long_data, size, portMAX_DELAY);
|
||||
|
||||
xSemaphoreTake(shutdown_sema, portMAX_DELAY);
|
||||
esp_websocket_client_close(client, portMAX_DELAY);
|
||||
|
@ -27,10 +27,13 @@ def get_my_ip():
|
||||
|
||||
|
||||
class WebsocketTestEcho(WebSocket):
|
||||
|
||||
def handleMessage(self):
|
||||
self.sendMessage(self.data)
|
||||
print('\n Server sent: {}\n'.format(self.data))
|
||||
if isinstance(self.data, bytes):
|
||||
print(f'\n Server received binary data: {self.data.hex()}\n')
|
||||
self.sendMessage(self.data, binary=True)
|
||||
else:
|
||||
print(f'\n Server received: {self.data}\n')
|
||||
self.sendMessage(self.data)
|
||||
|
||||
def handleConnected(self):
|
||||
print('Connection from: {}'.format(self.address))
|
||||
@ -86,6 +89,9 @@ def test_examples_protocol_websocket(dut):
|
||||
3. send and receive data
|
||||
"""
|
||||
|
||||
# Test for echo functionality:
|
||||
# Sends a series of simple "hello" messages to the WebSocket server and verifies that each one is echoed back correctly.
|
||||
# This tests the basic responsiveness and correctness of the WebSocket connection.
|
||||
def test_echo(dut):
|
||||
dut.expect('WEBSOCKET_EVENT_CONNECTED')
|
||||
for i in range(0, 5):
|
||||
@ -93,12 +99,16 @@ def test_examples_protocol_websocket(dut):
|
||||
print('All echos received')
|
||||
sys.stdout.flush()
|
||||
|
||||
# Test for clean closure of the WebSocket connection:
|
||||
# Ensures that the WebSocket can correctly receive a close frame and terminate the connection without issues.
|
||||
def test_close(dut):
|
||||
code = dut.expect(
|
||||
re.compile(
|
||||
b'websocket: Received closed message with code=(\\d*)'))[0]
|
||||
print('Received close frame with code {}'.format(code))
|
||||
|
||||
# Test for JSON message handling:
|
||||
# Sends a JSON formatted string and verifies that the received message matches the expected JSON structure.
|
||||
def test_json(dut, websocket):
|
||||
json_string = """
|
||||
[
|
||||
@ -118,7 +128,7 @@ def test_examples_protocol_websocket(dut):
|
||||
match = dut.expect(
|
||||
re.compile(b'Json=({[a-zA-Z0-9]*).*}')).group(0).decode()[5:]
|
||||
if match == str(data[0]):
|
||||
print('Sent message and received message are equal \n')
|
||||
print('\n Sent message and received message are equal \n')
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
raise ValueError(
|
||||
@ -126,6 +136,8 @@ def test_examples_protocol_websocket(dut):
|
||||
\nreceived: {}\nwith length {}'.format(
|
||||
data[0], len(data[0]), match, len(match)))
|
||||
|
||||
# Test for receiving long messages:
|
||||
# This sends a message with a specified length (2000 characters) to ensure the WebSocket can handle large data payloads. Repeated 3 times for reliability.
|
||||
def test_recv_long_msg(dut, websocket, msg_len, repeats):
|
||||
|
||||
send_msg = ''.join(
|
||||
@ -142,7 +154,7 @@ def test_examples_protocol_websocket(dut):
|
||||
recv_msg += match
|
||||
|
||||
if recv_msg == send_msg:
|
||||
print('Sent message and received message are equal \n')
|
||||
print('\n Sent message and received message are equal \n')
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
raise ValueError(
|
||||
@ -150,9 +162,50 @@ def test_examples_protocol_websocket(dut):
|
||||
\nreceived: {}\nwith length {}'.format(
|
||||
send_msg, len(send_msg), recv_msg, len(recv_msg)))
|
||||
|
||||
def test_fragmented_msg(dut):
|
||||
# Test for receiving the first fragment of a large message:
|
||||
# Verifies the WebSocket's ability to correctly process the initial segment of a fragmented message.
|
||||
def test_recv_fragmented_msg1(dut):
|
||||
dut.expect('websocket: Total payload length=2000, data_len=1024, current payload offset=0')
|
||||
|
||||
# Test for receiving the second fragment of a large message:
|
||||
# Confirms that the WebSocket can correctly handle and process the subsequent segment of a fragmented message.
|
||||
def test_recv_fragmented_msg2(dut):
|
||||
dut.expect('websocket: Total payload length=2000, data_len=976, current payload offset=1024')
|
||||
|
||||
# Test for receiving fragmented text messages:
|
||||
# Checks if the WebSocket can accurately reconstruct a message sent in several smaller parts.
|
||||
def test_fragmented_txt_msg(dut):
|
||||
dut.expect('Received=' + 32 * 'a' + 32 * 'b')
|
||||
print('Fragmented data received')
|
||||
print('\nFragmented data received\n')
|
||||
|
||||
# Extract the hexdump portion of the log line
|
||||
def parse_hexdump(line):
|
||||
match = re.search(r'\(.*\) Received binary data: ([0-9A-Fa-f ]+)', line)
|
||||
if match:
|
||||
hexdump = match.group(1).strip().replace(' ', '')
|
||||
# Convert the hexdump string to a bytearray
|
||||
return bytearray.fromhex(hexdump)
|
||||
return bytearray()
|
||||
|
||||
# Capture the binary log output from the DUT
|
||||
def test_fragmented_binary_msg(dut):
|
||||
match = dut.expect(r'\(.*\) Received binary data: .*')
|
||||
if match:
|
||||
line = match.group(0).strip()
|
||||
if isinstance(line, bytes):
|
||||
line = line.decode('utf-8')
|
||||
|
||||
# Parse the hexdump from the log line
|
||||
received_data = parse_hexdump(line)
|
||||
|
||||
# Create the expected bytearray with the specified pattern
|
||||
expected_data = bytearray([0, 0, 0, 0, 0, 1, 1, 1, 1, 1])
|
||||
|
||||
# Validate the received data
|
||||
assert received_data == expected_data, f'Received data does not match expected data. Received: {received_data}, Expected: {expected_data}'
|
||||
print('\nFragmented data received\n')
|
||||
else:
|
||||
assert False, 'Log line with binary data not found'
|
||||
|
||||
# Starting of the test
|
||||
try:
|
||||
@ -184,10 +237,12 @@ def test_examples_protocol_websocket(dut):
|
||||
dut.expect('Please enter uri of websocket endpoint', timeout=30)
|
||||
dut.write(uri)
|
||||
test_echo(dut)
|
||||
# Message length should exceed DUT's buffer size to test fragmentation, default is 1024 byte
|
||||
test_recv_long_msg(dut, ws, 2000, 3)
|
||||
test_json(dut, ws)
|
||||
test_fragmented_msg(dut)
|
||||
test_fragmented_txt_msg(dut)
|
||||
test_fragmented_binary_msg(dut)
|
||||
test_recv_fragmented_msg1(dut)
|
||||
test_recv_fragmented_msg2(dut)
|
||||
test_close(dut)
|
||||
else:
|
||||
print('DUT connecting to {}'.format(uri))
|
||||
|
@ -0,0 +1,14 @@
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_IDF_TARGET_LINUX=n
|
||||
CONFIG_WEBSOCKET_URI_FROM_STDIN=n
|
||||
CONFIG_WEBSOCKET_URI_FROM_STRING=y
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
|
||||
CONFIG_EXAMPLE_ETH_PHY_IP101=y
|
||||
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
|
||||
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
|
||||
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
|
||||
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=y
|
||||
CONFIG_ESP_WS_CLIENT_ENABLE_DYNAMIC_BUFFER=y
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(wifi_remote): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py esp_wifi_remote
|
||||
tag_format: wifi_remote-v$version
|
||||
version: 0.2.1
|
||||
version: 0.2.3
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,19 @@
|
||||
# Changelog
|
||||
|
||||
## [0.2.3](https://github.com/espressif/esp-protocols/commits/wifi_remote-v0.2.3)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fix server event/command race condtion using eventfd ([732b1d5](https://github.com/espressif/esp-protocols/commit/732b1d5))
|
||||
- Lock server before marshalling events ([9e13870](https://github.com/espressif/esp-protocols/commit/9e13870))
|
||||
|
||||
## [0.2.2](https://github.com/espressif/esp-protocols/commits/wifi_remote-v0.2.2)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Added more netif options for eppp connection ([24ce867](https://github.com/espressif/esp-protocols/commit/24ce867))
|
||||
- Do not restrict EPPP config to RSA keys only ([f05c765](https://github.com/espressif/esp-protocols/commit/f05c765), [#570](https://github.com/espressif/esp-protocols/issues/570))
|
||||
|
||||
## [0.2.1](https://github.com/espressif/esp-protocols/commits/wifi_remote-v0.2.1)
|
||||
|
||||
### Bug Fixes
|
||||
|
@ -14,7 +14,7 @@ idf_component_register(INCLUDE_DIRS include
|
||||
${src_wifi_is_remote}
|
||||
PRIV_INCLUDE_DIRS eppp
|
||||
REQUIRES esp_event esp_netif
|
||||
PRIV_REQUIRES esp_wifi esp-tls)
|
||||
PRIV_REQUIRES esp_wifi esp-tls vfs)
|
||||
|
||||
idf_component_get_property(wifi esp_wifi COMPONENT_LIB)
|
||||
target_link_libraries(${wifi} PUBLIC ${COMPONENT_LIB})
|
||||
|
@ -30,6 +30,23 @@ endchoice
|
||||
help
|
||||
Pin number of UART RX.
|
||||
|
||||
config ESP_WIFI_REMOTE_EPPP_NETIF_PRIORITY
|
||||
int "Routing priority of eppp netif"
|
||||
default 100
|
||||
range 0 256
|
||||
help
|
||||
Set the priority of the wifi-remote netif.
|
||||
The bigger the number the higher the priority.
|
||||
The interface which is up and with the highest priority will act as a default GW.
|
||||
|
||||
config ESP_WIFI_REMOTE_EPPP_NETIF_DESCRIPTION
|
||||
string "eppp network interface description"
|
||||
default "example_netif_sta"
|
||||
help
|
||||
Textual description of the wifi remote network interface.
|
||||
By default it is set to "example_netif_sta" to be used in IDF protocol example
|
||||
as default wifi station substitution.
|
||||
|
||||
config ESP_WIFI_REMOTE_EPPP_SERVER_CA
|
||||
string "Servers CA certificate"
|
||||
default "--- Please copy content of the CA certificate ---"
|
||||
|
@ -16,5 +16,7 @@ __attribute__((weak)) esp_netif_t *wifi_remote_eppp_init(eppp_type_t role)
|
||||
config.transport = EPPP_TRANSPORT_UART;
|
||||
config.uart.tx_io = CONFIG_ESP_WIFI_REMOTE_EPPP_UART_TX_PIN;
|
||||
config.uart.rx_io = CONFIG_ESP_WIFI_REMOTE_EPPP_UART_RX_PIN;
|
||||
config.ppp.netif_description = CONFIG_ESP_WIFI_REMOTE_EPPP_NETIF_DESCRIPTION;
|
||||
config.ppp.netif_prio = CONFIG_ESP_WIFI_REMOTE_EPPP_NETIF_PRIORITY;
|
||||
return eppp_open(role, &config, portMAX_DELAY);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ const char *TAG = "rpc_client";
|
||||
|
||||
const unsigned char ca_crt[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_CA "\n-----END CERTIFICATE-----";
|
||||
const unsigned char crt[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_CRT "\n-----END CERTIFICATE-----";
|
||||
const unsigned char key[] = "-----BEGIN RSA PRIVATE KEY-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_KEY "\n-----END RSA PRIVATE KEY-----";
|
||||
const unsigned char key[] = "-----BEGIN PRIVATE KEY-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_KEY "\n-----END PRIVATE KEY-----";
|
||||
// TODO: Add option to supply keys and certs via a global symbol (file)
|
||||
|
||||
}
|
||||
|
@ -129,6 +129,15 @@ public:
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int get_socket_fd()
|
||||
{
|
||||
int sock;
|
||||
if (esp_tls_get_conn_sockfd(tls_, &sock) != ESP_OK) {
|
||||
return -1;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
RpcHeader get_header()
|
||||
{
|
||||
RpcHeader header{};
|
||||
|
@ -16,7 +16,7 @@ struct esp_wifi_remote_mac_t {
|
||||
};
|
||||
|
||||
struct esp_wifi_remote_eppp_ip_event {
|
||||
uint32_t id;
|
||||
int32_t id;
|
||||
esp_netif_ip_info_t wifi_ip;
|
||||
esp_netif_ip_info_t ppp_ip;
|
||||
esp_netif_dns_info_t dns;
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "eppp_link.h"
|
||||
#include "wifi_remote_rpc_params.h"
|
||||
#include "lwip/apps/snmp.h"
|
||||
#include "esp_vfs.h"
|
||||
#include "esp_vfs_eventfd.h"
|
||||
|
||||
extern "C" esp_netif_t *wifi_remote_eppp_init(eppp_type_t role);
|
||||
|
||||
@ -25,14 +27,81 @@ const char *TAG = "rpc_server";
|
||||
|
||||
const unsigned char ca_crt[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_CA "\n-----END CERTIFICATE-----";
|
||||
const unsigned char crt[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_CRT "\n-----END CERTIFICATE-----";
|
||||
const unsigned char key[] = "-----BEGIN RSA PRIVATE KEY-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_KEY "\n-----END RSA PRIVATE KEY-----";
|
||||
const unsigned char key[] = "-----BEGIN PRIVATE KEY-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_KEY "\n-----END PRIVATE KEY-----";
|
||||
// TODO: Add option to supply keys and certs via a global symbol (file)
|
||||
|
||||
}
|
||||
|
||||
using namespace server;
|
||||
|
||||
struct Events {
|
||||
api_id type;
|
||||
int32_t id;
|
||||
esp_wifi_remote_eppp_ip_event *ip_data{nullptr};
|
||||
bool clean_ip_data{true};
|
||||
esp_err_t create_ip_data()
|
||||
{
|
||||
ip_data = new (std::nothrow) esp_wifi_remote_eppp_ip_event;
|
||||
return ip_data ? ESP_OK : ESP_ERR_NO_MEM;
|
||||
}
|
||||
~Events()
|
||||
{
|
||||
if (clean_ip_data) {
|
||||
delete ip_data;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Sync {
|
||||
friend class RpcInstance;
|
||||
public:
|
||||
esp_err_t put(Events &ev)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(xQueueSend(queue, &ev, pdMS_TO_TICKS(queue_timeout)), ESP_FAIL, TAG, "Failed to queue event %" PRIi32, ev.id);
|
||||
ev.clean_ip_data = false; // IP data were successfully sent to the queue, will free manually after receiving from it
|
||||
uint64_t event_queued = 1;
|
||||
write(fd, &event_queued, sizeof(event_queued)); // trigger the wait loop that
|
||||
return ESP_OK;
|
||||
}
|
||||
Events get()
|
||||
{
|
||||
Events ev{};
|
||||
if (!xQueueReceive(queue, &ev, 0)) {
|
||||
ev.type = api_id::ERROR;
|
||||
}
|
||||
return ev;
|
||||
}
|
||||
esp_err_t init()
|
||||
{
|
||||
queue = xQueueCreate(max_items, sizeof(Events));
|
||||
esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
|
||||
esp_vfs_eventfd_register(&config);
|
||||
fd = eventfd(0, EFD_SUPPORT_ISR);
|
||||
return queue == nullptr || fd < 0 ? ESP_ERR_NO_MEM : ESP_OK;
|
||||
}
|
||||
~Sync()
|
||||
{
|
||||
if (queue) {
|
||||
vQueueDelete(queue);
|
||||
}
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
int fd{-1};
|
||||
// Used to trigger task by either an internal event or rpc command
|
||||
static const int NONE = 0;
|
||||
static const int ERROR = 1;
|
||||
static const int EVENT = 2;
|
||||
static const int RPC = 4;
|
||||
private:
|
||||
QueueHandle_t queue{nullptr};
|
||||
const int max_items = 15;
|
||||
const int queue_timeout = 200;
|
||||
};
|
||||
|
||||
class RpcInstance {
|
||||
friend class Sync;
|
||||
public:
|
||||
RpcEngine rpc{role::SERVER};
|
||||
int sock{-1};
|
||||
@ -43,11 +112,12 @@ public:
|
||||
ESP_RETURN_ON_ERROR(start_server(), TAG, "Failed to start RPC server");
|
||||
ESP_RETURN_ON_ERROR(rpc.init(), TAG, "Failed to init RPC engine");
|
||||
ESP_RETURN_ON_ERROR(esp_netif_napt_enable(netif), TAG, "Failed to enable NAPT");
|
||||
ESP_RETURN_ON_ERROR(sync.init(), TAG, "Failed to init event queue");
|
||||
ESP_RETURN_ON_ERROR(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, handler, this), TAG, "Failed to register event");
|
||||
ESP_RETURN_ON_ERROR(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, handler, this), TAG, "Failed to register event");
|
||||
return xTaskCreate(task, "server", 8192, this, 5, nullptr) == pdTRUE ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
Sync sync;
|
||||
private:
|
||||
esp_netif_t *netif{nullptr};
|
||||
static void task(void *ctx)
|
||||
@ -81,23 +151,24 @@ private:
|
||||
esp_err_t wifi_event(int32_t id)
|
||||
{
|
||||
ESP_LOGI(TAG, "Received WIFI event %" PRIi32, id);
|
||||
ESP_RETURN_ON_ERROR(rpc.send(api_id::WIFI_EVENT, &id), TAG, "Failed to marshall WiFi event");
|
||||
Events ev{api_id::WIFI_EVENT, id, nullptr};
|
||||
ESP_RETURN_ON_ERROR(sync.put(ev), TAG, "Failed to queue WiFi event");
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t ip_event(int32_t id, ip_event_got_ip_t *ip_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Received IP event %" PRIi32, id);
|
||||
esp_wifi_remote_eppp_ip_event ip_event{};
|
||||
ip_event.id = id;
|
||||
Events ev{api_id::IP_EVENT, id, nullptr};
|
||||
if (ip_data->esp_netif) {
|
||||
// marshall additional data, only if netif available
|
||||
ESP_RETURN_ON_ERROR(esp_netif_get_dns_info(ip_data->esp_netif, ESP_NETIF_DNS_MAIN, &ip_event.dns), TAG, "Failed to get DNS info");
|
||||
ESP_LOGI(TAG, "Main DNS:" IPSTR, IP2STR(&ip_event.dns.ip.u_addr.ip4));
|
||||
memcpy(&ip_event.wifi_ip, &ip_data->ip_info, sizeof(ip_event.wifi_ip));
|
||||
ESP_RETURN_ON_ERROR(esp_netif_get_ip_info(netif, &ip_event.ppp_ip), TAG, "Failed to get IP info");
|
||||
ESP_RETURN_ON_ERROR(ev.create_ip_data(), TAG, "Failed to allocate event data");
|
||||
ev.ip_data->id = id;
|
||||
ESP_RETURN_ON_ERROR(esp_netif_get_dns_info(ip_data->esp_netif, ESP_NETIF_DNS_MAIN, &ev.ip_data->dns), TAG, "Failed to get DNS info");
|
||||
ESP_LOGI(TAG, "Main DNS:" IPSTR, IP2STR(&ev.ip_data->dns.ip.u_addr.ip4));
|
||||
memcpy(&ev.ip_data->wifi_ip, &ip_data->ip_info, sizeof(ev.ip_data->wifi_ip));
|
||||
ESP_RETURN_ON_ERROR(esp_netif_get_ip_info(netif, &ev.ip_data->ppp_ip), TAG, "Failed to get IP info");
|
||||
ESP_LOGI(TAG, "IP address:" IPSTR, IP2STR(&ip_data->ip_info.ip));
|
||||
}
|
||||
ESP_RETURN_ON_ERROR(rpc.send(api_id::IP_EVENT, &ip_event), TAG, "Failed to marshal IP event");
|
||||
ESP_RETURN_ON_ERROR(sync.put(ev), TAG, "Failed to queue IP event");
|
||||
return ESP_OK;
|
||||
}
|
||||
static void handler(void *ctx, esp_event_base_t base, int32_t id, void *data)
|
||||
@ -110,11 +181,83 @@ private:
|
||||
instance->ip_event(id, ip_data);
|
||||
}
|
||||
}
|
||||
int select()
|
||||
{
|
||||
struct timeval timeout = { .tv_sec = 1, .tv_usec = 0};
|
||||
int rpc_sock = rpc.get_socket_fd();
|
||||
|
||||
ESP_RETURN_ON_FALSE(rpc_sock != -1, Sync::ERROR, TAG, "failed ot get rpc socket");
|
||||
fd_set readset;
|
||||
fd_set errset;
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&errset);
|
||||
FD_SET(rpc_sock, &readset);
|
||||
FD_SET(sync.fd, &readset);
|
||||
FD_SET(rpc_sock, &errset);
|
||||
int ret = ::select(std::max(rpc_sock, 5) + 1, &readset, nullptr, &errset, &timeout);
|
||||
if (ret == 0) {
|
||||
ESP_LOGV(TAG, "poll_read: select - Timeout before any socket was ready!");
|
||||
return Sync::NONE;
|
||||
}
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "select error: %d", errno);
|
||||
return Sync::ERROR;
|
||||
}
|
||||
if (FD_ISSET(rpc_sock, &errset)) {
|
||||
int sock_errno = 0;
|
||||
uint32_t optlen = sizeof(sock_errno);
|
||||
getsockopt(rpc_sock, SOL_SOCKET, SO_ERROR, &sock_errno, &optlen);
|
||||
ESP_LOGE(TAG, "select failed, socket errno = %d", sock_errno);
|
||||
return Sync::ERROR;
|
||||
}
|
||||
int result = Sync::NONE;
|
||||
if (FD_ISSET(rpc_sock, &readset)) {
|
||||
result |= Sync::RPC;
|
||||
}
|
||||
if (FD_ISSET(sync.fd, &readset)) {
|
||||
result |= Sync::EVENT;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
esp_err_t marshall_events()
|
||||
{
|
||||
api_id type;
|
||||
do {
|
||||
Events ev = sync.get();
|
||||
type = ev.type;
|
||||
if (ev.type == api_id::WIFI_EVENT) {
|
||||
ESP_RETURN_ON_ERROR(rpc.send(api_id::WIFI_EVENT, &ev.id), TAG, "Failed to marshall WiFi event");
|
||||
} else if (ev.type == api_id::IP_EVENT && ev.ip_data) {
|
||||
ESP_RETURN_ON_ERROR(rpc.send(api_id::IP_EVENT, ev.ip_data), TAG, "Failed to marshal IP event");
|
||||
}
|
||||
} while (type != api_id::ERROR);
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t perform()
|
||||
{
|
||||
auto res = select();
|
||||
if (res == Sync::ERROR) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (res & Sync::EVENT) {
|
||||
uint64_t data;
|
||||
read(sync.fd, &data, sizeof(data));
|
||||
if (marshall_events() != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
if (res & Sync::RPC) {
|
||||
if (handle_commands() != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t handle_commands()
|
||||
{
|
||||
auto header = rpc.get_header();
|
||||
ESP_LOGI(TAG, "Received header id %d", (int) header.id);
|
||||
|
||||
switch (header.id) {
|
||||
case api_id::SET_MODE: {
|
||||
auto req = rpc.get_payload<wifi_mode_t>(api_id::SET_MODE, header);
|
||||
|
@ -59,6 +59,11 @@ WEAK void esp_wifi_internal_free_rx_buffer(void *buffer)
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
WEAK esp_err_t esp_wifi_internal_tx_by_ref(wifi_interface_t ifx, void *buffer, size_t len, void *netstack_buf)
|
||||
{
|
||||
return esp_wifi_internal_tx(ifx, buffer, (uint16_t)len);
|
||||
}
|
||||
|
||||
WEAK int esp_wifi_internal_tx(wifi_interface_t ifx, void *buffer, uint16_t len)
|
||||
{
|
||||
if (ifx == WIFI_IF_STA && s_tx_cb[0]) {
|
||||
|
@ -1,5 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function gen_pkey { # Params: [KEY_FILE]
|
||||
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 | openssl pkcs8 -topk8 -outform PEM -nocrypt -out $1
|
||||
}
|
||||
|
||||
function sign_with_ca { # Params: [KEY_FILE] [CN] [CRT_FILE]
|
||||
openssl req -out request.csr -key $1 -subj "/CN=$2" -new -sha256
|
||||
openssl x509 -req -in request.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out $3 -days 365 -sha256
|
||||
}
|
||||
|
||||
function export_config { # Params: [FILE/CONFIG_NAME]
|
||||
content=`cat $1 | sed '/---/d' | tr -d '\n'`
|
||||
echo "CONFIG_ESP_WIFI_REMOTE_EPPP_$1=\"${content}\""
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage $0 <SERVER_CN> [CLIENT_CN]"
|
||||
exit 1;
|
||||
@ -12,30 +26,27 @@ echo "Server's CN: $SERVER_CN"
|
||||
echo "Client's CN: $CLIENT_CN"
|
||||
|
||||
## First create our own CA
|
||||
openssl genrsa -out ca.key 2048
|
||||
gen_pkey ca.key
|
||||
openssl req -new -x509 -subj "/C=CZ/CN=Espressif" -days 365 -key ca.key -out ca.crt
|
||||
# will use the same CA for both server and client side
|
||||
cp ca.crt SERVER_CA
|
||||
cp ca.crt CLIENT_CA
|
||||
|
||||
# Server side
|
||||
openssl genrsa -out srv.key 2048
|
||||
openssl req -out srv.csr -key srv.key -subj "/CN=$SERVER_CN" -new -sha256
|
||||
openssl x509 -req -in srv.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out srv.crt -days 365 -sha256
|
||||
gen_pkey SERVER_KEY
|
||||
sign_with_ca SERVER_KEY $SERVER_CN SERVER_CRT
|
||||
|
||||
# Client side
|
||||
openssl genrsa -out client.key 2048
|
||||
openssl req -out client.csr -key client.key -subj "/CN=$CLIENT_CN" -new -sha256
|
||||
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256
|
||||
gen_pkey CLIENT_KEY
|
||||
sign_with_ca CLIENT_KEY $CLIENT_CN CLIENT_CRT
|
||||
|
||||
## Generate config options
|
||||
# Client side:
|
||||
CA_CRT=`cat ca.crt | sed '/---/d' | tr -d '\n'`
|
||||
echo "CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_CA=\"$CA_CRT\""
|
||||
CLIENT_CRT=`cat client.crt | sed '/---/d' | tr -d '\n'`
|
||||
echo "CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_CRT=\"$CLIENT_CRT\""
|
||||
CLIENT_KEY=`cat client.key | sed '/---/d' | tr -d '\n'`
|
||||
echo "CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_KEY=\"$CLIENT_KEY\""
|
||||
## Server side (here it uses the same CA)
|
||||
echo "CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_CA=\"$CA_CRT\""
|
||||
SERVER_CRT=`cat srv.crt | sed '/---/d' | tr -d '\n'`
|
||||
echo "CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_CRT=\"$SERVER_CRT\""
|
||||
SERVER_KEY=`cat srv.key | sed '/---/d' | tr -d '\n'`
|
||||
echo "CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_KEY=\"$SERVER_KEY\""
|
||||
echo -e "\n# Client side: need own cert and key and ca-cert for server validation"
|
||||
for f in SERVER_CA CLIENT_CRT CLIENT_KEY; do
|
||||
export_config $f
|
||||
done
|
||||
|
||||
echo -e "\n# Server side: need own cert and key and ca-cert for client validation"
|
||||
for f in CLIENT_CA SERVER_CRT SERVER_KEY; do
|
||||
export_config $f
|
||||
done
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 0.2.1
|
||||
version: 0.2.3
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_wifi_remote
|
||||
description: Utility wrapper for esp_wifi functionality on remote targets
|
||||
dependencies:
|
||||
@ -6,5 +6,5 @@ dependencies:
|
||||
version: '>=0.1'
|
||||
idf:
|
||||
version: '>=5.3'
|
||||
# espressif/esp_hosted:
|
||||
# version: '*'
|
||||
espressif/esp_hosted:
|
||||
version: '>=0.0.6'
|
||||
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(mdns): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py mdns
|
||||
tag_format: mdns-v$version
|
||||
version: 1.3.0
|
||||
version: 1.3.2
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,22 @@
|
||||
# Changelog
|
||||
|
||||
## [1.3.2](https://github.com/espressif/esp-protocols/commits/mdns-v1.3.2)
|
||||
|
||||
### Features
|
||||
|
||||
- add check of instance when handling PTR query ([6af6ca5](https://github.com/espressif/esp-protocols/commit/6af6ca5))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fix of mdns afl tests ([139166c](https://github.com/espressif/esp-protocols/commit/139166c))
|
||||
- remove same protocol services with different instances ([042533a](https://github.com/espressif/esp-protocols/commit/042533a))
|
||||
|
||||
## [1.3.1](https://github.com/espressif/esp-protocols/commits/mdns-v1.3.1)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- free txt value len ([afd98bb](https://github.com/espressif/esp-protocols/commit/afd98bb))
|
||||
|
||||
## [1.3.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.3.0)
|
||||
|
||||
### Features
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: "1.3.0"
|
||||
version: "1.3.2"
|
||||
description: mDNS
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/mdns
|
||||
dependencies:
|
||||
|
@ -1871,6 +1871,7 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
|
||||
packet->id = parsed_packet->id;
|
||||
|
||||
mdns_parsed_question_t *q = parsed_packet->questions;
|
||||
uint32_t out_record_nums = 0;
|
||||
while (q) {
|
||||
shared = q->type == MDNS_TYPE_PTR || q->type == MDNS_TYPE_SDPTR || !parsed_packet->probe;
|
||||
if (q->type == MDNS_TYPE_SRV || q->type == MDNS_TYPE_TXT) {
|
||||
@ -1878,14 +1879,36 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
|
||||
if (service == NULL || !_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
} else if (q->service && q->proto) {
|
||||
mdns_srv_item_t *service = _mdns_server->services;
|
||||
while (service) {
|
||||
if (_mdns_service_match_ptr_question(service->service, q)) {
|
||||
if (!_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
mdns_parsed_record_t *r = parsed_packet->records;
|
||||
bool is_record_exist = false;
|
||||
while (r) {
|
||||
if (service->service->instance && r->host) {
|
||||
if (_mdns_service_match_instance(service->service, r->host, r->service, r->proto, NULL) && r->ttl > (MDNS_ANSWER_PTR_TTL / 2)) {
|
||||
is_record_exist = true;
|
||||
break;
|
||||
}
|
||||
} else if (!service->service->instance && !r->host) {
|
||||
if (_mdns_service_match(service->service, r->service, r->proto, NULL) && r->ttl > (MDNS_ANSWER_PTR_TTL / 2)) {
|
||||
is_record_exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
if (!is_record_exist) {
|
||||
if (!_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
}
|
||||
}
|
||||
service = service->next;
|
||||
@ -1894,22 +1917,31 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
|
||||
if (!_mdns_create_answer_from_hostname(packet, q->host, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
} else if (q->type == MDNS_TYPE_ANY) {
|
||||
if (!_mdns_append_host_list(&packet->answers, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
||||
} else if (q->type == MDNS_TYPE_PTR) {
|
||||
mdns_host_item_t *host = mdns_get_host_item(q->host);
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, NULL, host, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
|
||||
} else if (!_mdns_alloc_answer(&packet->answers, q->type, NULL, NULL, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
} else {
|
||||
out_record_nums++;
|
||||
}
|
||||
|
||||
if (parsed_packet->src_port != MDNS_SERVICE_PORT && // Repeat the queries only for "One-Shot mDNS queries"
|
||||
@ -1943,6 +1975,10 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
|
||||
}
|
||||
q = q->next;
|
||||
}
|
||||
if (out_record_nums == 0) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
if (unicast || !send_flush) {
|
||||
memcpy(&packet->dst, &parsed_packet->src, sizeof(esp_ip_addr_t));
|
||||
packet->port = parsed_packet->src_port;
|
||||
@ -3336,7 +3372,11 @@ static bool _mdns_question_matches(mdns_parsed_question_t *question, uint16_t ty
|
||||
&& !strcasecmp(service->service->service, question->service)
|
||||
&& !strcasecmp(service->service->proto, question->proto)
|
||||
&& !strcasecmp(MDNS_DEFAULT_DOMAIN, question->domain)) {
|
||||
return true;
|
||||
if (!service->service->instance) {
|
||||
return true;
|
||||
} else if (service->service->instance && question->host && !strcasecmp(service->service->instance, question->host)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (service && (type == MDNS_TYPE_SRV || type == MDNS_TYPE_TXT)) {
|
||||
const char *name = _mdns_get_service_instance_name(service->service);
|
||||
@ -3635,6 +3675,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
parsed_packet->id = header.id;
|
||||
esp_netif_ip_addr_copy(&parsed_packet->src, &packet->src);
|
||||
parsed_packet->src_port = packet->src_port;
|
||||
parsed_packet->records = NULL;
|
||||
|
||||
if (header.questions) {
|
||||
uint8_t qs = header.questions;
|
||||
@ -3821,7 +3862,12 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
_mdns_search_result_add_ptr(search_result, name->host, name->service, name->proto,
|
||||
packet->tcpip_if, packet->ip_protocol, ttl);
|
||||
} else if ((discovery || ours) && !name->sub && _mdns_name_is_ours(name)) {
|
||||
if (discovery && (service = _mdns_get_service_item(name->service, name->proto, NULL))) {
|
||||
if (name->host[0]) {
|
||||
service = _mdns_get_service_item_instance(name->host, name->service, name->proto, NULL);
|
||||
} else {
|
||||
service = _mdns_get_service_item(name->service, name->proto, NULL);
|
||||
}
|
||||
if (discovery && service) {
|
||||
_mdns_remove_parsed_question(parsed_packet, MDNS_TYPE_SDPTR, service);
|
||||
} else if (service && parsed_packet->questions && !parsed_packet->probe) {
|
||||
_mdns_remove_parsed_question(parsed_packet, type, service);
|
||||
@ -3831,6 +3877,45 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
_mdns_remove_scheduled_answer(packet->tcpip_if, packet->ip_protocol, type, service);
|
||||
}
|
||||
}
|
||||
if (service) {
|
||||
mdns_parsed_record_t *record = malloc(sizeof(mdns_parsed_record_t));
|
||||
if (!record) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
goto clear_rx_packet;
|
||||
}
|
||||
record->next = parsed_packet->records;
|
||||
parsed_packet->records = record;
|
||||
record->type = MDNS_TYPE_PTR;
|
||||
record->record_type = MDNS_ANSWER;
|
||||
record->ttl = ttl;
|
||||
record->host = NULL;
|
||||
record->service = NULL;
|
||||
record->proto = NULL;
|
||||
if (name->host[0]) {
|
||||
record->host = malloc(MDNS_NAME_BUF_LEN);
|
||||
if (!record->host) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
goto clear_rx_packet;
|
||||
}
|
||||
memcpy(record->host, name->host, MDNS_NAME_BUF_LEN);
|
||||
}
|
||||
if (name->service[0]) {
|
||||
record->service = malloc(MDNS_NAME_BUF_LEN);
|
||||
if (!record->service) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
goto clear_rx_packet;
|
||||
}
|
||||
memcpy(record->service, name->service, MDNS_NAME_BUF_LEN);
|
||||
}
|
||||
if (name->proto[0]) {
|
||||
record->proto = malloc(MDNS_NAME_BUF_LEN);
|
||||
if (!record->proto) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
goto clear_rx_packet;
|
||||
}
|
||||
memcpy(record->proto, name->proto, MDNS_NAME_BUF_LEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type == MDNS_TYPE_SRV) {
|
||||
mdns_result_t *result = NULL;
|
||||
@ -4161,6 +4246,21 @@ clear_rx_packet:
|
||||
}
|
||||
free(question);
|
||||
}
|
||||
while (parsed_packet->records) {
|
||||
mdns_parsed_record_t *record = parsed_packet->records;
|
||||
parsed_packet->records = parsed_packet->records->next;
|
||||
if (record->host) {
|
||||
free(record->host);
|
||||
}
|
||||
if (record->service) {
|
||||
free(record->service);
|
||||
}
|
||||
if (record->proto) {
|
||||
free(record->proto);
|
||||
}
|
||||
record->next = NULL;
|
||||
free(record);
|
||||
}
|
||||
free(parsed_packet);
|
||||
if (browse_result_instance) {
|
||||
free(browse_result_instance);
|
||||
@ -4739,7 +4839,7 @@ free_txt:
|
||||
free((char *)(txt[i].value));
|
||||
}
|
||||
free(txt);
|
||||
free(r->txt_value_len);
|
||||
free(txt_value_len);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5200,28 +5300,57 @@ static void _mdns_execute_action(mdns_action_t *action)
|
||||
break;
|
||||
case ACTION_SERVICE_DEL:
|
||||
a = _mdns_server->services;
|
||||
if (action->data.srv_del.service) {
|
||||
if (_mdns_server->services == action->data.srv_del.service) {
|
||||
_mdns_server->services = a->next;
|
||||
_mdns_send_bye(&a, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(a->service);
|
||||
_mdns_free_service(a->service);
|
||||
free(a);
|
||||
} else {
|
||||
while (a->next && a->next != action->data.srv_del.service) {
|
||||
a = a->next;
|
||||
mdns_srv_item_t *b = a;
|
||||
if (action->data.srv_del.instance) {
|
||||
while (a) {
|
||||
if (_mdns_service_match_instance(a->service, action->data.srv_del.instance,
|
||||
action->data.srv_del.service, action->data.srv_del.proto,
|
||||
action->data.srv_del.hostname)) {
|
||||
if (_mdns_server->services != a) {
|
||||
b->next = a->next;
|
||||
} else {
|
||||
_mdns_server->services = a->next;
|
||||
}
|
||||
_mdns_send_bye(&a, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(a->service);
|
||||
_mdns_free_service(a->service);
|
||||
free(a);
|
||||
break;
|
||||
}
|
||||
if (a->next == action->data.srv_del.service) {
|
||||
mdns_srv_item_t *b = a->next;
|
||||
a->next = a->next->next;
|
||||
_mdns_send_bye(&b, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(b->service);
|
||||
_mdns_free_service(b->service);
|
||||
free(b);
|
||||
b = a;
|
||||
a = a->next;
|
||||
}
|
||||
} else {
|
||||
while (a) {
|
||||
if (_mdns_service_match(a->service, action->data.srv_del.service, action->data.srv_del.proto,
|
||||
action->data.srv_del.hostname)) {
|
||||
if (_mdns_server->services != a) {
|
||||
b->next = a->next;
|
||||
_mdns_send_bye(&a, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(a->service);
|
||||
_mdns_free_service(a->service);
|
||||
free(a);
|
||||
a = b->next;
|
||||
continue;
|
||||
} else {
|
||||
_mdns_server->services = a->next;
|
||||
_mdns_send_bye(&a, 1, false);
|
||||
_mdns_remove_scheduled_service_packets(a->service);
|
||||
_mdns_free_service(a->service);
|
||||
free(a);
|
||||
a = _mdns_server->services;
|
||||
b = a;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
b = a;
|
||||
a = a->next;
|
||||
}
|
||||
}
|
||||
|
||||
free((char *)action->data.srv_del.instance);
|
||||
free((char *)action->data.srv_del.service);
|
||||
free((char *)action->data.srv_del.proto);
|
||||
free((char *)action->data.srv_del.hostname);
|
||||
break;
|
||||
case ACTION_SERVICES_CLEAR:
|
||||
_mdns_send_final_bye(false);
|
||||
@ -6401,6 +6530,16 @@ esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const cha
|
||||
if (!s) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
mdns_subtype_t *srv_subtype = s->service->subtype;
|
||||
while (srv_subtype) {
|
||||
if (strcmp(srv_subtype->subtype, subtype) == 0) {
|
||||
// The same subtype has already been added
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
srv_subtype = srv_subtype->next;
|
||||
}
|
||||
|
||||
mdns_action_t *action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
|
||||
if (!action) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
@ -6489,12 +6628,40 @@ esp_err_t mdns_service_remove_for_host(const char *instance, const char *service
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
action->type = ACTION_SERVICE_DEL;
|
||||
action->data.srv_del.service = s;
|
||||
action->data.srv_del.instance = NULL;
|
||||
action->data.srv_del.hostname = NULL;
|
||||
if (!_str_null_or_empty(instance)) {
|
||||
action->data.srv_del.instance = strndup(instance, MDNS_NAME_BUF_LEN - 1);
|
||||
if (!action->data.srv_del.instance) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_str_null_or_empty(hostname)) {
|
||||
action->data.srv_del.hostname = strndup(hostname, MDNS_NAME_BUF_LEN - 1);
|
||||
if (!action->data.srv_del.hostname) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
action->data.srv_del.service = strndup(service, MDNS_NAME_BUF_LEN - 1);
|
||||
action->data.srv_del.proto = strndup(proto, MDNS_NAME_BUF_LEN - 1);
|
||||
if (!action->data.srv_del.service || !action->data.srv_del.proto) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (xQueueSend(_mdns_server->action_queue, &action, (TickType_t)0) != pdPASS) {
|
||||
free(action);
|
||||
return ESP_ERR_NO_MEM;
|
||||
goto fail;
|
||||
}
|
||||
return ESP_OK;
|
||||
|
||||
fail:
|
||||
free((char *)action->data.srv_del.instance);
|
||||
free((char *)action->data.srv_del.service);
|
||||
free((char *)action->data.srv_del.proto);
|
||||
free((char *)action->data.srv_del.hostname);
|
||||
free(action);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_remove(const char *service_type, const char *proto)
|
||||
@ -7437,7 +7604,7 @@ free_txt:
|
||||
free((char *)(txt[i].value));
|
||||
}
|
||||
free(txt);
|
||||
free(r->txt_value_len);
|
||||
free(txt_value_len);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -450,7 +450,10 @@ typedef struct {
|
||||
mdns_srv_item_t *service;
|
||||
} srv_add;
|
||||
struct {
|
||||
mdns_srv_item_t *service;
|
||||
char *instance;
|
||||
char *service;
|
||||
char *proto;
|
||||
char *hostname;
|
||||
} srv_del;
|
||||
struct {
|
||||
mdns_srv_item_t *service;
|
||||
|
@ -195,6 +195,7 @@
|
||||
#define CONFIG_HEAP_TRACING_OFF 1
|
||||
#define CONFIG_LOG_DEFAULT_LEVEL_INFO 1
|
||||
#define CONFIG_LOG_DEFAULT_LEVEL 3
|
||||
#define CONFIG_LOG_MAXIMUM_LEVEL 3
|
||||
#define CONFIG_LOG_COLORS 1
|
||||
#define CONFIG_LOG_TIMESTAMP_SOURCE_RTOS 1
|
||||
#define CONFIG_LWIP_LOCAL_HOSTNAME "espressif"
|
||||
|
30
test_app/CMakeLists.txt
Normal file
30
test_app/CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
include($ENV{IDF_PATH}/tools/cmake/version.cmake)
|
||||
|
||||
# Add newly added components to one of these lines:
|
||||
set(EXTRA_COMPONENT_DIRS
|
||||
../components/eppp_link
|
||||
../components/esp_modem
|
||||
../components/esp_mqtt_cxx
|
||||
../components/esp_websocket_client
|
||||
../components/console_cmd_ifconfig
|
||||
../components/console_cmd_ping
|
||||
../components/console_cmd_wifi
|
||||
../components/console_simple_init
|
||||
../components/mbedtls_cxx
|
||||
../components/mdns)
|
||||
|
||||
|
||||
# !This section should NOT be touched when adding new component!
|
||||
# Take all components in EXTRA_COMPONENT_DIRS, strip leading '../' and add it to TEST_COMPONENTS
|
||||
# The build system will build and link unit tests, if the component contains 'test' subdirectory
|
||||
set(TEST_COMPONENTS "" CACHE STRING "List of components to test")
|
||||
foreach (CMP_DIR ${EXTRA_COMPONENT_DIRS})
|
||||
string(SUBSTRING ${CMP_DIR} 3 100 STRIPPED_CMP) # There should be no component name longer than 100 bytes...
|
||||
list(APPEND TEST_COMPONENTS ${STRIPPED_CMP})
|
||||
endforeach()
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(esp_protocols_test_app)
|
3
test_app/main/CMakeLists.txt
Normal file
3
test_app/main/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "test_app_main.c"
|
||||
INCLUDE_DIRS ""
|
||||
REQUIRES unity)
|
14
test_app/main/test_app_main.c
Normal file
14
test_app/main/test_app_main.c
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
unity_run_all_tests();
|
||||
UNITY_END();
|
||||
}
|
5
test_app/partitions.csv
Normal file
5
test_app/partitions.csv
Normal file
@ -0,0 +1,5 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x6000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
factory, app, factory, , 2M,
|
|
4
test_app/pytest_test_app.py
Normal file
4
test_app/pytest_test_app.py
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
def test_app(dut):
|
||||
dut.expect_unity_test_output(timeout=240)
|
15
test_app/sdkconfig.defaults
Normal file
15
test_app/sdkconfig.defaults
Normal file
@ -0,0 +1,15 @@
|
||||
CONFIG_ESP_INT_WDT=n
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
|
||||
# Run-time checks of Heap and Stack
|
||||
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
|
||||
CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y
|
||||
CONFIG_COMPILER_STACK_CHECK=y
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=16000
|
||||
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
|
||||
|
||||
CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y
|
Reference in New Issue
Block a user