Compare commits

...

55 Commits

Author SHA1 Message Date
david-cermak
db7baaffba Merge pull request #887 from david-cermak/fix/eppp_uart_deps
[eppp]: Fix uart driver deps with new IDF
2025-09-15 13:41:53 +02:00
David Cermak
1ea93a866b bump(eppp): 1.1.1 -> 1.1.2
1.1.2
Bug Fixes
- Update uart driver deps per IDF > v5.3 (92e14607)
2025-09-15 12:55:14 +02:00
David Cermak
92e1460721 fix(eppp): Update uart driver deps per IDF > v5.3 2025-09-15 12:55:08 +02:00
david-cermak
858d38b55f Merge pull request #885 from david-cermak/fix/eppp_uart_channels
[eppp]: Fix getting context for channel API
2025-09-09 17:03:00 +02:00
David Cermak
6428e68c8e bump(eppp): 1.1.0 -> 1.1.1
1.1.1
Bug Fixes
- Fix getting context for channel API (94563cdc)
- Cover more combinations in build tests (e0b8de8f)
2025-09-09 16:18:11 +02:00
David Cermak
94563cdc1f fix(eppp): Fix getting context for channel API 2025-09-09 13:42:18 +02:00
David Cermak
e0b8de8f38 fix(eppp): Cover more combinations in build tests 2025-09-09 13:42:18 +02:00
Guilherme Alves Ferreira
34b6681576 Merge pull request #771 from glmfe/feat/add-http-redir
feat(websocket): Add websocket HTTP redirect
2025-09-03 12:31:20 -03:00
david-cermak
1f7828f629 Merge pull request #875 from david-cermak/update/eppp_v1.1
[eppp]: Bump 1.0.1 -> 1.1.0
2025-09-03 16:03:05 +02:00
david-cermak
e74db36ebb Merge pull request #881 from david-cermak/fix/minor_ci_fixes
Fixup common CI issues with v6.0 idf-tools
2025-09-03 13:16:49 +02:00
David Cermak
f8d2ed2eed fix(tls_cxx): Remove unnnecessary warning ignore 2025-09-03 12:07:21 +02:00
David Cermak
8bba3a9734 fix(mdns): Host test to use hw_support include dir 2025-09-03 11:37:47 +02:00
David Cermak
9fbb6e6d0a fix(mosq): Fix the version check 2025-09-03 10:20:53 +02:00
David Cermak
e599cd826b fix(common): Fixup common CI issues with v6.0 2025-09-03 10:06:13 +02:00
david-cermak
e2d36b4fbd Merge pull request #879 from david-cermak/fix/modem_sim_napt
[modem_sim]: Enable LWIP-NAPT by default in modem simulator
2025-09-03 09:27:41 +02:00
david-cermak
82a784baf4 Merge pull request #880 from david-cermak/fix/modem_ci
[modem]: Fix recent CI issues
2025-09-02 18:01:05 +02:00
David Cermak
15140e04c6 fix(modem): Fix CI build issues with IDFv6.0
* Fix C++ console struct init in examples
* VFS deprecation in tests
* Add conditional defines over wakeup-cause
2025-09-02 15:47:00 +02:00
glmfe
ce1560acb1 feat(websocket): Add websocket HTTP redirect
- Handle 301 status (moved permanently) and redirect the connection to the new host.
2025-09-02 09:52:20 -03:00
David Cermak
e1be830fb7 fix(modem_sim): Enable LWIP-NAPT by default in modem simulator
As this mode is used by PPP clients
2025-09-01 18:47:47 +02:00
david-cermak
b7cfa31a0b Merge pull request #878 from david-cermak/bump/mosq_2.0.20.4
bump(mosq): 2.0.20~3 -> 2.0.20~4
2025-09-01 11:54:20 +02:00
David Cermak
845a1e2ef8 fix(mosq): Skip serverless example build on master
Due to esp-peer's long list dependencies, which are usually based
from stable IDF releases
2025-09-01 10:08:11 +02:00
David Cermak
6ae7a4d2ba bump(mosq): 2.0.20~3 -> 2.0.20~4
2.0.20~4
Features
- Update brokerless example to work with esp-peer (76e45f72)
Bug Fixes
- drop newlib from PRIV_REQUIRES (6318022c)
- Make esp-peer build optional (03df9ae9)
- Fix esp_webRTC deprecation with new FreeRTOS (78ae2559)
2025-09-01 09:55:34 +02:00
david-cermak
4d52982a69 Merge pull request #876 from Lapshin/master
fix: drop newlib from PRIV_REQUIRES
2025-09-01 09:27:09 +02:00
Alexey Lapshin
6318022cda fix: drop newlib from PRIV_REQUIRES 2025-08-28 16:18:22 +07:00
David Cermak
13591ade3d bump(eppp): 1.0.1 -> 1.1.0
1.1.0
Features
- Add support for UART flow control (cd57f1bb, #870)
Bug Fixes
- Fix SPI transport to allow already init GPIO ISR (497ee2d6, #868)
- Fix stack-overflow in ping task for TUN netif (b2568a3d, #867)
Updated
- ci(common): Update test component dir for IDFv6.0 (18418c83)
2025-08-27 15:11:15 +02:00
david-cermak
d09b302b9e Merge pull request #872 from david-cermak/fix/eppp_minor_fixes
[eppp]: Minor fixes v1.0
2025-08-27 08:57:25 +02:00
david-cermak
39e2333adb Merge pull request #871 from david-cermak/fix/modem_sim_docs
[modem_sim]: Add initial modem simulator docs
2025-08-26 11:00:46 +02:00
David Cermak
cd57f1bb13 feat(eppp): Add support for UART flow control
Closes https://github.com/espressif/esp-protocols/issues/870
2025-08-25 16:30:57 +02:00
David Cermak
497ee2d6d4 fix(eppp): Fix SPI transport to allow already init GPIO ISR
Closes https://github.com/espressif/esp-protocols/issues/868
2025-08-25 15:23:07 +02:00
David Cermak
b2568a3d83 fix(eppp): Fix stack-overflow in ping task for TUN netif
Closes https://github.com/espressif/esp-protocols/issues/867
2025-08-25 14:51:59 +02:00
david-cermak
58a21e39d0 Merge pull request #837 from david-cermak/feat/modem_tcp_client_extend
[modem]: Extend tcp-client example
2025-08-25 08:53:51 +02:00
David Cermak
9c7ee07755 feat(modem_sim): Add initial modem simulator docs 2025-08-25 08:52:48 +02:00
David Cermak
14d3cb6bd1 fix(modem): Add support for ESP-AT based tcp-client example 2025-08-25 06:38:57 +02:00
david-cermak
ccdb45ee94 Merge pull request #869 from david-cermak/fix/test_build_v6.0
fix(CI): Fix test component dir after IDFv6.0 update
2025-08-22 15:01:59 +02:00
David Cermak
18418c83ff ci(common): Update test component dir for IDFv6.0
Update websocket, mdns and eppp test apps
2025-08-22 14:23:43 +02:00
david-cermak
ecb7dae502 Merge pull request #863 from david-cermak/feat/modem_without_ppp
[modem]: Support esp-modem use without PPP
2025-08-21 12:46:29 +02:00
david-cermak
958ff6a584 Merge pull request #866 from david-cermak/fix/modem_sim
[modem_sim]: ESP-AT build failure on v5.4
2025-08-18 17:12:53 +02:00
David Cermak
5ea83be7ce fix(modem_sim): Fix build step 2025-08-18 16:35:07 +02:00
david-cermak
33a3ec54b6 Merge pull request #865 from david-cermak/fix/eppp_ipv4_only
[eppp]: Support for IPv4-only mode
2025-08-18 12:03:07 +02:00
David Cermak
c91578c827 bump(eppp): 1.0.0 -> 1.0.1
1.0.1
Bug Fixes
- Support for IPv4-only mode (653328ba, #864)
2025-08-18 11:09:33 +02:00
David Cermak
653328ba07 fix(eppp): Support for IPv4-only mode
Closes https://github.com/espressif/esp-protocols/issues/864
2025-08-18 11:03:17 +02:00
David Cermak
858f85706d feat(modem): Support esp-modem use without PPP
Closes https://github.com/espressif/esp-protocols/issues/851
2025-08-14 17:29:50 +02:00
david-cermak
f8748e026d Merge pull request #862 from david-cermak/fix/mbedtls_cookie
fix(mbedtls_cxx): Enable mbedtls cookie support
2025-08-13 12:41:48 +02:00
David Cermak
479122b21d fix(mbedtls_cxx): Enable mbedtls cookie support 2025-08-13 12:05:14 +02:00
david-cermak
e8ce8f4739 Merge pull request #861 from david-cermak/fix/minor_links
fix(ci): Use default mqtt public endpoint
2025-08-12 16:23:12 +02:00
David Cermak
03df9ae957 fix(mosq): Make esp-peer build optional 2025-08-12 16:07:02 +02:00
David Cermak
35fa0b1d42 ci(common): Fix the link to CONTRIBUTING guidelines 2025-08-12 14:29:08 +02:00
David Cermak
e9d9b3a8bd fix(modem): Use idf-build-apps for building target tests
Also updates default mqtt broker public endpoint
2025-08-12 14:29:03 +02:00
Euripedes
07e8eddcb6 Merge pull request #856 from david-cermak/fix/mosquitto_build
[mosq]: Fix esp_webRTC-lib deprecation with new FreeRTOS
2025-07-29 08:06:05 +02:00
David Cermak
78ae25598b fix(mosq): Fix esp_webRTC deprecation with new FreeRTOS 2025-07-25 18:55:59 +02:00
david-cermak
ffeee3e87a Merge pull request #852 from david-cermak/fix/mqtt_endpoints
fix(examples): Address MQTT public endpoint availability
2025-07-25 16:04:24 +02:00
David Cermak
6d5411941b fix(modem): Make MQTT public broker endpoint configurable 2025-07-25 11:02:36 +02:00
David Cermak
e71365f835 fix(examples): Use configured public broker for MQTT linux test
Also updated pre-commit hook versions, as some don't work in py3.12
2025-07-25 11:01:53 +02:00
david-cermak
8dbf0e4561 Merge pull request #855 from cosmicKev/mdns-fix-custom-allocator
Fixes case where we create our own malloc/free allocators, therefore … (IDFGH-16053)
2025-07-25 07:48:09 +02:00
kevin filipe
63bf70914b fix(mdns): Fixes case where we create our own malloc/free allocators, therefore we need to call mdns_mem_free and not free 2025-07-24 13:21:55 +02:00
61 changed files with 775 additions and 81 deletions

View File

@@ -33,6 +33,9 @@ jobs:
shell: bash
working-directory: ${{matrix.test.path}}
run: |
if [[ "${{ matrix.idf_ver }}" == "release-v5.3" || "${{ matrix.idf_ver }}" == "release-v5.4" ]]; then
export EXPECTED_WARNING="unknown kconfig symbol 'LWIP_USE_ESP_GETADDRINFO'"
fi
. ${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

View File

@@ -59,10 +59,11 @@ jobs:
- name: Build with IDF-${{ matrix.idf_ver }}
shell: bash
run: |
. ${GITHUB_WORKSPACE}/ci/config_env.sh
. ${IDF_PATH}/export.sh
python -m pip install idf-build-apps
python ./ci/build_apps.py examples/mqtt -l -t linux
timeout 5 ./examples/mqtt/build_linux_default/esp_mqtt_demo.elf | tee test.log || true
python ./ci/build_apps.py examples/mqtt -l -t linux -r 'sdkconfig.ci'
timeout 5 ./examples/mqtt/build_linux/esp_mqtt_demo.elf | tee test.log || true
grep 'MQTT_EVENT_DATA' test.log
run_on_target:

View File

@@ -34,18 +34,16 @@ jobs:
IDF_TARGET: ${{ matrix.idf_target }}
SDKCONFIG: sdkconfig.ci.${{ matrix.test.app }}
shell: bash
working-directory: ${{ env.TEST_DIR }}
run: |
. ${GITHUB_WORKSPACE}/ci/config_env.sh
. ${IDF_PATH}/export.sh
rm -rf sdkconfig build
[ -f ${SDKCONFIG} ] && cp ${SDKCONFIG} sdkconfig.defaults
idf.py set-target ${{ matrix.idf_target }}
idf.py build
$GITHUB_WORKSPACE/ci/clean_build_artifacts.sh ${GITHUB_WORKSPACE}/${TEST_DIR}/build
python -m pip install idf-build-apps
python ./ci/build_apps.py ${{ env.TEST_DIR }} -t ${{ matrix.idf_target }} -r 'sdkconfig.ci.${{ matrix.test.app }}'
$GITHUB_WORKSPACE/ci/clean_build_artifacts.sh ${GITHUB_WORKSPACE}/${TEST_DIR}/build_${{ matrix.idf_target }}
- uses: actions/upload-artifact@v4
with:
name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
path: ${{ env.TEST_DIR }}/build
path: ${{ env.TEST_DIR }}/build_${{ matrix.idf_target }}
if-no-files-found: error
target_tests_esp_modem:

View File

@@ -11,17 +11,21 @@ jobs:
build_modem_sim:
if: contains(github.event.pull_request.labels.*.name, 'modem_sim') || github.event_name == 'push'
name: Build
strategy:
matrix:
idf_ver: ["release-v5.4"]
runs-on: ubuntu-22.04
container: espressif/idf:${{ matrix.idf_ver }}
runs-on: ubuntu-latest
steps:
- name: Checkout esp-protocols
uses: actions/checkout@v3
- name: Checkout idf
uses: actions/checkout@v3
with:
repository: espressif/esp-idf
ref: 8ad0d3d8f2faab752635bee36070313c47c07a13
path: idf
- name: Build ESP-AT with IDF-${{ matrix.idf_ver }}
shell: bash
run: |
export IDF_PATH=$GITHUB_WORKSPACE/idf
${IDF_PATH}/install.sh
cd common_components/modem_sim
./install.sh
source export.sh

View File

@@ -16,8 +16,11 @@ jobs:
idf_ver: ["latest", "release-v5.5", "release-v5.4", "release-v5.3", "release-v5.2", "release-v5.1"]
example: ["broker", "serverless_mqtt"]
exclude:
# serverless_mqtt is not supported on v5.1 and master (esp-peer dependency)
- idf_ver: "release-v5.1"
example: "serverless_mqtt" # serverless_mqtt is not supported due to esp-peer
example: "serverless_mqtt"
- idf_ver: "latest"
example: "serverless_mqtt"
runs-on: ubuntu-22.04
container: espressif/idf:${{ matrix.idf_ver }}

View File

@@ -39,7 +39,7 @@ jobs:
if ! pre-commit run --from-ref origin/HEAD --to-ref HEAD --hook-stage manual --show-diff-on-failure ; then
echo ""
echo "::notice::It looks like the commits in this PR have been made without having pre-commit hooks installed."
echo "::notice::Please see https://github.com/espressif/esp-protocols/CONTRIBUTING.md for instructions."
echo "::notice::Please see https://github.com/espressif/esp-protocols/blob/master/CONTRIBUTING.md for instructions."
echo ""
exit 1
fi

View File

@@ -25,12 +25,8 @@ repos:
(?x)^(
.*.py
)$
- repo: https://github.com/myint/unify
rev: v0.5
hooks:
- id: unify
- repo: https://github.com/pre-commit/mirrors-yapf
rev: "v0.32.0"
- repo: https://github.com/google/yapf
rev: "v0.43.0"
hooks:
- id: yapf
args: ['style={based_on_style: google, column_limit: 160, indent_width: 4}']
@@ -39,7 +35,7 @@ repos:
hooks:
- id: isort
- repo: https://github.com/myint/eradicate/
rev: v2.1.0
rev: 3.0.0
hooks:
- id: eradicate
- repo: https://github.com/espressif/check-copyright/

View File

@@ -65,6 +65,7 @@ if __name__ == '__main__':
sys.exit(
build_apps(apps,
verbose=2,
dry_run=False,
keep_going=False,
no_preserve=args.delete,

7
ci/config_env.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# This script is used to set some common variables for the CI pipeline.
set -e
# MQTT public broker URI
export CI_MQTT_BROKER_URI="test.mosquitto.org"

View File

@@ -0,0 +1,51 @@
# Modem Simulator Component
A Wi-Fi modem simulator that extends ESP-AT with PPP server capabilities, turning ESP32 into a fully functional Wi-Fi modem. Perfect for testing AT commands and PPP connections without real hardware dependencies.
## What it does
- Extends ESP-AT firmware with PPP server functionality
- Provides DATA mode for raw IP communication
- Enables existing communication stacks (MQTT, HTTP, custom protocols) to work over Wi-Fi
- Ideal for testing ESP-Modem library and CI reliability
## Quick Start
```bash
cd common_components/modem_sim
./install.sh
source export.sh
idf.py build
```
## Custom Platform/Module
```bash
./install.sh PLATFORM_ESP32S3 WROOM-32
```
## Configuration
The `sdkconfig.defaults` includes:
- Wi-Fi and Bluetooth enabled
- PPP server support
- AT commands for HTTP/MQTT
- 4MB flash configuration
## Project Structure
```
modem_sim/
├── install.sh # Installation script
├── export.sh # Environment setup
├── sdkconfig.defaults # Default configuration
├── pppd_cmd/ # Custom PPP commands
└── modem_sim_esp32/ # Generated ESP-AT build
```
## Use Cases
- Testing ESP-Modem library without real hardware
- Quick Wi-Fi connectivity for existing communication stacks
- CI/CD testing with reliable modem simulation
- Development and debugging of AT command implementations

View File

@@ -75,3 +75,5 @@ CONFIG_AT_HTTP_COMMAND_SUPPORT=y
CONFIG_AT_BLE_COMMAND_SUPPORT=n
CONFIG_AT_BLE_HID_COMMAND_SUPPORT=n
CONFIG_AT_BLUFI_COMMAND_SUPPORT=n
CONFIG_LWIP_IP_FORWARD=y
CONFIG_LWIP_IPV4_NAPT=y

View File

@@ -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: 1.0.0
version: 1.1.2
version_files:
- idf_component.yml

View File

@@ -1,5 +1,39 @@
# Changelog
## [1.1.2](https://github.com/espressif/esp-protocols/commits/eppp-v1.1.2)
### Bug Fixes
- Update uart driver deps per IDF > v5.3 ([92e14607](https://github.com/espressif/esp-protocols/commit/92e14607))
## [1.1.1](https://github.com/espressif/esp-protocols/commits/eppp-v1.1.1)
### Bug Fixes
- Fix getting context for channel API ([94563cdc](https://github.com/espressif/esp-protocols/commit/94563cdc))
- Cover more combinations in build tests ([e0b8de8f](https://github.com/espressif/esp-protocols/commit/e0b8de8f))
## [1.1.0](https://github.com/espressif/esp-protocols/commits/eppp-v1.1.0)
### Features
- Add support for UART flow control ([cd57f1bb](https://github.com/espressif/esp-protocols/commit/cd57f1bb), [#870](https://github.com/espressif/esp-protocols/issues/870))
### Bug Fixes
- Fix SPI transport to allow already init GPIO ISR ([497ee2d6](https://github.com/espressif/esp-protocols/commit/497ee2d6), [#868](https://github.com/espressif/esp-protocols/issues/868))
- Fix stack-overflow in ping task for TUN netif ([b2568a3d](https://github.com/espressif/esp-protocols/commit/b2568a3d), [#867](https://github.com/espressif/esp-protocols/issues/867))
### Updated
- ci(common): Update test component dir for IDFv6.0 ([18418c83](https://github.com/espressif/esp-protocols/commit/18418c83))
## [1.0.1](https://github.com/espressif/esp-protocols/commits/eppp-v1.0.1)
### Bug Fixes
- Support for IPv4-only mode ([653328ba](https://github.com/espressif/esp-protocols/commit/653328ba), [#864](https://github.com/espressif/esp-protocols/issues/864))
## [1.0.0](https://github.com/espressif/esp-protocols/commits/eppp-v1.0.0)
### Features

View File

@@ -1,5 +1,5 @@
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER "5.3")
set(driver_deps esp_driver_gpio esp_driver_spi)
set(driver_deps esp_driver_gpio esp_driver_spi esp_driver_uart esp_driver_sdio)
else()
set(driver_deps driver)
endif()

View File

@@ -65,12 +65,13 @@ static err_t tun_output_v4(struct netif *netif, struct pbuf *p, const ip4_addr_t
LWIP_UNUSED_ARG(ipaddr);
return tun_output(netif, p);
}
#if LWIP_IPV6
static err_t tun_output_v6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
{
LWIP_UNUSED_ARG(ipaddr);
return tun_output(netif, p);
}
#endif
static err_t tun_init(struct netif *netif)
{
if (netif == NULL) {
@@ -151,9 +152,12 @@ static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args)
}
if (IP_IS_V4(&target_addr)) {
ESP_LOGD(TAG, "\n--- %s ping statistics ---\n", inet_ntoa(*ip_2_ip4(&target_addr)));
} else {
}
#if LWIP_IPV6
else {
ESP_LOGD(TAG, "\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&target_addr)));
}
#endif
ESP_LOGI(TAG, "%" PRIu32 " packets transmitted, %" PRIu32 " received, %" PRIu32 "%% packet loss, time %" PRIu32 "ms\n",
transmitted, received, loss, total_time_ms);
esp_ping_delete_session(hdl);
@@ -163,12 +167,19 @@ esp_err_t eppp_check_connection(esp_netif_t *netif)
{
esp_err_t ret = ESP_OK;
esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG();
#if CONFIG_LOG_MAXIMUM_LEVEL > 3
config.task_stack_size += 1024; // Some additional stack needed for verbose logs
#endif
config.count = 100;
ESP_LOGI(TAG, "Checking connection on EPPP interface #%" PRIu32, config.interface);
ip_addr_t target_addr = {0};
esp_netif_ip_info_t ip;
esp_netif_get_ip_info(netif, &ip);
#if LWIP_IPV6
target_addr.u_addr.ip4.addr = ip.gw.addr;
#else
target_addr.addr = ip.gw.addr;
#endif
config.target_addr = target_addr;
esp_ping_callbacks_t cbs = {
.cb_args = netif,

View File

@@ -208,7 +208,9 @@ static esp_err_t init_master(struct eppp_config_spi_s *config, struct eppp_spi *
};
ESP_GOTO_ON_ERROR(gpio_config(&io_conf), err_dev, TAG, "Failed to config interrupt GPIO");
ESP_GOTO_ON_ERROR(gpio_install_isr_service(0), err_dev, TAG, "Failed to install GPIO ISR");
ret = gpio_install_isr_service(0);
ESP_GOTO_ON_FALSE(ret == ESP_OK || ret == ESP_ERR_INVALID_STATE /* In case the GPIO ISR already installed */,
ret, err_dev, TAG, "Failed to install GPIO ISR");
ESP_GOTO_ON_ERROR(gpio_set_intr_type(config->intr, GPIO_INTR_ANYEDGE), err_dev, TAG, "Failed to set ISR type");
ESP_GOTO_ON_ERROR(gpio_isr_handler_add(config->intr, gpio_isr_handler, h), err_dev, TAG, "Failed to add ISR handler");
return ESP_OK;
@@ -468,9 +470,6 @@ err:
if (h->ready_semaphore) {
vSemaphoreDelete(h->ready_semaphore);
}
if (h->out_queue) {
vQueueDelete(h->out_queue);
}
free(h);
return NULL;
}

View File

@@ -80,12 +80,12 @@ static esp_err_t init_uart(struct eppp_uart *h, struct eppp_config_uart_s *confi
uart_config.data_bits = UART_DATA_8_BITS;
uart_config.parity = UART_PARITY_DISABLE;
uart_config.stop_bits = UART_STOP_BITS_1;
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
uart_config.flow_ctrl = config->flow_control;
uart_config.source_clk = UART_SCLK_DEFAULT;
ESP_RETURN_ON_ERROR(uart_driver_install(h->uart_port, config->rx_buffer_size, 0, config->queue_size, &h->uart_event_queue, 0), TAG, "Failed to install UART");
ESP_RETURN_ON_ERROR(uart_param_config(h->uart_port, &uart_config), TAG, "Failed to set params");
ESP_RETURN_ON_ERROR(uart_set_pin(h->uart_port, config->tx_io, config->rx_io, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE), TAG, "Failed to set UART pins");
ESP_RETURN_ON_ERROR(uart_set_pin(h->uart_port, config->tx_io, config->rx_io, config->rts_io, config->cts_io), TAG, "Failed to set UART pins");
ESP_RETURN_ON_ERROR(uart_set_rx_timeout(h->uart_port, 1), TAG, "Failed to set UART Rx timeout");
return ESP_OK;
}
@@ -157,6 +157,8 @@ static void process_packet(esp_netif_t *netif, uart_port_t uart_port, size_t ava
esp_netif_receive(netif, in_buf + buf_start + sizeof(struct header), payload_size, NULL);
} else {
#ifdef CONFIG_EPPP_LINK_CHANNELS_SUPPORT
struct eppp_handle *handle = esp_netif_get_io_driver(netif);
struct eppp_uart *h = __containerof(handle, struct eppp_uart, parent);
if (h->parent.channel_rx) {
h->parent.channel_rx(netif, channel, in_buf + buf_start + sizeof(struct header), payload_size);
}
@@ -269,6 +271,7 @@ eppp_transport_handle_t eppp_uart_init(struct eppp_config_uart_s *config)
ESP_GOTO_ON_ERROR(init_uart(h, config), err, TAG, "Failed to init UART");
return &h->parent;
err:
free(h);
return NULL;
}

View File

@@ -0,0 +1,4 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_EPPP_LINK_DEVICE_SPI=y
CONFIG_EPPP_LINK_CHANNELS_SUPPORT=y
CONFIG_EPPP_LINK_USES_PPP=y

View File

@@ -0,0 +1,3 @@
CONFIG_IDF_TARGET="esp32c3"
CONFIG_EPPP_LINK_DEVICE_UART=y
CONFIG_EPPP_LINK_CHANNELS_SUPPORT=y

View File

@@ -1,4 +1 @@
CONFIG_LWIP_PPP_SUPPORT=y
CONFIG_LWIP_PPP_SERVER_SUPPORT=y
CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n
CONFIG_LWIP_PPP_DEBUG_ON=y

View File

@@ -0,0 +1,4 @@
CONFIG_IDF_TARGET="esp32s2"
CONFIG_EPPP_LINK_DEVICE_SPI=y
CONFIG_EPPP_LINK_CHANNELS_SUPPORT=y
CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n

View File

@@ -0,0 +1,4 @@
CONFIG_IDF_TARGET="esp32c2"
CONFIG_EPPP_LINK_DEVICE_UART=y
CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n
CONFIG_EPPP_LINK_USES_PPP=y

View File

@@ -0,0 +1 @@
CONFIG_LWIP_IPV6=n

View File

@@ -1,6 +1,3 @@
CONFIG_LWIP_IP_FORWARD=y
CONFIG_LWIP_IPV4_NAPT=y
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
CONFIG_LWIP_PPP_SUPPORT=y
CONFIG_LWIP_PPP_SERVER_SUPPORT=y
CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n

View File

@@ -1,4 +1,4 @@
version: 1.0.0
version: 1.1.2
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:

View File

@@ -34,6 +34,9 @@ extern "C" {
.rx_io = 26, \
.queue_size = 16, \
.rx_buffer_size = 1024, \
.rts_io = -1, \
.cts_io = -1, \
.flow_control = 0, \
}, \
#define EPPP_DEFAULT_SDIO_CONFIG() \
@@ -135,6 +138,9 @@ typedef struct eppp_config_t {
int rx_io;
int queue_size;
int rx_buffer_size;
int rts_io;
int cts_io;
int flow_control;
} uart;
struct eppp_config_sdio_s {

View File

@@ -1,7 +1,15 @@
# The following four lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/tools/unit-test-app/components)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "6.0")
set(test_component_dir $ENV{IDF_PATH}/tools/test_apps/components)
else()
set(test_component_dir $ENV{IDF_PATH}/tools/unit-test-app/components)
endif()
set(EXTRA_COMPONENT_DIRS ${test_component_dir})
project(test_app)

View File

@@ -103,4 +103,14 @@ menu "esp-modem"
Set this to 'y' if you're making changes to the actual sources of
the AT command definitions (typically in esp_modem_command_declare.inc)
config ESP_MODEM_USE_PPP_MODE
bool "Use PPP mode"
default y
select LWIP_PPP_SUPPORT
help
If enabled, the library can use PPP netif from lwip.
This is the default and most common setting.
But it's possible to disable it and use only AT commands,
in this case it's not required to enable LWIP_PPP_SUPPORT.
endmenu

View File

@@ -63,13 +63,12 @@ void ConsoleCommand::RegisterCommand(const char *command, const char *help, cons
arg_type end = { .end = arg_end(1) };
arg_table.emplace_back(end);
const esp_console_cmd_t command_def = {
.command = command,
.help = help,
.hint = nullptr,
.func = command_func_pts[last_command],
.argtable = &arg_table[0]
};
esp_console_cmd_t command_def = { };
command_def.command = command;
command_def.help = help;
command_def.hint = nullptr;
command_def.func = command_func_pts[last_command];
command_def.argtable = &arg_table[0];
ESP_ERROR_CHECK(esp_console_cmd_register(&command_def));
last_command++;
console_commands.emplace_back(this);

View File

@@ -21,6 +21,7 @@
#include "cxx_include/esp_modem_dte.hpp"
#include "esp_modem_config.h"
#include "cxx_include/esp_modem_api.hpp"
#include "esp_idf_version.h"
#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
#include "esp_modem_usb_config.h"
#include "cxx_include/esp_modem_usb_api.hpp"
@@ -29,6 +30,12 @@
#include "console_helper.hpp"
#include "my_module_dce.hpp"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
#define GET_WAKEUP_CAUSE() esp_sleep_get_wakeup_causes()
#else
#define GET_WAKEUP_CAUSE() esp_sleep_get_wakeup_cause()
#endif
#if defined(CONFIG_EXAMPLE_FLOW_CONTROL_NONE)
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_NONE
#elif defined(CONFIG_EXAMPLE_FLOW_CONTROL_SW)
@@ -208,7 +215,7 @@ extern "C" void app_main(void)
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
switch (esp_sleep_get_wakeup_cause()) {
switch (GET_WAKEUP_CAUSE()) {
case ESP_SLEEP_WAKEUP_TIMER:
if (esp_modem::modem_mode::CMUX_MODE == mode_rtc) {
ESP_LOGI(TAG, "Deep sleep reset\n");
@@ -428,7 +435,7 @@ extern "C" void app_main(void)
const ConsoleCommand SetDeepSleep("set_deep_sleep", "Put esp32 to deep sleep", &deep_sleep_args, sizeof(deep_sleep_args), [&](ConsoleCommand * c) {
int tout = c->get_int_of(&DeepSleepArgs::timeout);
ESP_LOGI(TAG, "Entering deep sleep for %d sec", tout);
ESP_LOGI(TAG, "Wakeup Cause: %d ", esp_sleep_get_wakeup_cause());
ESP_LOGI(TAG, "Wakeup Cause: %d ", GET_WAKEUP_CAUSE());
esp_deep_sleep(tout * 1000000);
return 0;
});

View File

@@ -1,7 +1,11 @@
set(module_dir "generic_module")
if (CONFIG_EXAMPLE_MODEM_DEVICE_BG96)
set(device_srcs sock_commands_bg96.cpp)
elseif(CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600)
set(device_srcs sock_commands_sim7600.cpp)
elseif(CONFIG_EXAMPLE_MODEM_DEVICE_ESPAT)
set(device_srcs sock_commands_espat.cpp)
set(module_dir "espat_module")
endif()
if(CONFIG_ESP_MODEM_ENABLE_DEVELOPMENT_MODE)
@@ -14,4 +18,4 @@ idf_component_register(SRCS "modem_client.cpp"
"${command_dir}/sock_dce.cpp"
"tcp_transport_at.cpp"
"${device_srcs}"
INCLUDE_DIRS "." "${command_dir}")
INCLUDE_DIRS "." "${command_dir}" "${module_dir}")

View File

@@ -18,8 +18,26 @@ menu "Example Configuration"
bool "SIM7600"
help
SIM7600 is Multi-Band LTE-TDD/LTE-FDD/HSPA+ and GSM/GPRS/EDGE module
config EXAMPLE_MODEM_DEVICE_ESPAT
bool "ESP-AT"
help
ESP-AT firmware for ESP32 modules with WiFi connectivity
endchoice
if EXAMPLE_MODEM_DEVICE_ESPAT
config EXAMPLE_WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) to connect to.
config EXAMPLE_WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2).
endif
config EXAMPLE_MODEM_APN
string "Set MODEM APN"
default "internet"

View File

@@ -8,6 +8,7 @@
#include "cxx_include/esp_modem_api.hpp"
#include <cxx_include/esp_modem_dce_factory.hpp>
#include "sock_commands.hpp"
#include "sock_module.hpp"
#include <sys/socket.h>
#pragma once
@@ -97,8 +98,8 @@ private:
std::shared_ptr<esp_modem::DTE> &dte;
};
class DCE : public ::esp_modem::GenericModule {
using esp_modem::GenericModule::GenericModule;
class DCE : public Module {
using Module::Module;
public:
/**

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_modem_config.h"
#include "cxx_include/esp_modem_api.hpp"
#pragma once
namespace sock_dce {
class Module: public esp_modem::GenericModule {
using esp_modem::GenericModule::GenericModule;
public:
esp_modem::command_result sync() override;
esp_modem::command_result set_echo(bool on) override;
esp_modem::command_result set_pdp_context(esp_modem::PdpContext &pdp) override;
};
}

View File

@@ -8,6 +8,7 @@
#include "cxx_include/esp_modem_api.hpp"
#include <cxx_include/esp_modem_dce_factory.hpp>
#include "sock_commands.hpp"
#include "sock_module.hpp"
#include <sys/socket.h>
#pragma once
@@ -97,8 +98,8 @@ private:
std::shared_ptr<esp_modem::DTE> &dte;
};
class DCE : public ::esp_modem::GenericModule {
using esp_modem::GenericModule::GenericModule;
class DCE : public Module {
using Module::Module;
public:
// --- ESP-MODEM command module starts here ---

View File

@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_modem_config.h"
#include "cxx_include/esp_modem_api.hpp"
#pragma once
namespace sock_dce {
using Module = esp_modem::GenericModule;
}

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -23,8 +23,8 @@
#include "tcp_transport_mbedtls.h"
#include "tcp_transport_at.h"
#define BROKER_URL "mqtt.eclipseprojects.io"
#define BROKER_PORT 8883
#define BROKER_URL "test.mosquitto.org"
#define BROKER_PORT 1883
static const char *TAG = "modem_client";
@@ -114,7 +114,7 @@ extern "C" void app_main(void)
mqtt_config.broker.address.port = BROKER_PORT;
mqtt_config.session.message_retransmit_timeout = 10000;
#ifndef CONFIG_EXAMPLE_CUSTOM_TCP_TRANSPORT
mqtt_config.broker.address.uri = "mqtts://127.0.0.1";
mqtt_config.broker.address.uri = "mqtt://127.0.0.1";
dce->start_listening(BROKER_PORT);
#else
mqtt_config.broker.address.uri = "mqtt://" BROKER_URL;
@@ -124,14 +124,14 @@ extern "C" void app_main(void)
mqtt_config.network.transport = ssl;
#endif
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);
esp_mqtt_client_register_event(mqtt_client, static_cast<esp_mqtt_event_id_t>(ESP_EVENT_ANY_ID), mqtt_event_handler, NULL);
esp_mqtt_client_register_event(mqtt_client, static_cast<esp_mqtt_event_id_t>(ESP_EVENT_ANY_ID), mqtt_event_handler, nullptr);
esp_mqtt_client_start(mqtt_client);
#ifndef CONFIG_EXAMPLE_CUSTOM_TCP_TRANSPORT
if (!dce->connect(BROKER_URL, BROKER_PORT)) {
ESP_LOGE(TAG, "Failed to start DCE");
return;
}
while (1) {
while (true) {
while (dce->perform_sock()) {
ESP_LOGV(TAG, "...performing");
}

View File

@@ -0,0 +1,366 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <charconv>
#include <cstring>
#include "sock_commands.hpp"
#include "cxx_include/esp_modem_command_library_utils.hpp"
#include "sock_dce.hpp"
#include "sock_module.hpp"
static const char *TAG = "sock_commands_espat";
namespace sock_dce {
using namespace esp_modem;
command_result Module::sync()
{
return dce_commands::generic_command_common(dte.get(), "AT\r\n");
}
command_result Module::set_echo(bool on)
{
return dce_commands::generic_command_common(dte.get(), "ATE0\r\n");
}
command_result Module::set_pdp_context(PdpContext &pdp)
{
return command_result::OK;
}
}
namespace sock_commands {
using namespace esp_modem;
command_result net_open(CommandableIf *t)
{
ESP_LOGV(TAG, "%s", __func__);
// Set WiFi mode to station
auto ret = dce_commands::generic_command(t, "AT+CWMODE=1\r\n", "OK", "ERROR", 5000);
if (ret != command_result::OK) {
ESP_LOGE(TAG, "Failed to set WiFi mode");
return ret;
}
// Connect to WiFi network
std::string wifi_cmd = "AT+CWJAP=\"" CONFIG_EXAMPLE_WIFI_SSID "\",\"" CONFIG_EXAMPLE_WIFI_PASSWORD "\"\r\n";
ret = dce_commands::generic_command(t, wifi_cmd, "OK", "ERROR", 15000);
if (ret != command_result::OK) {
ESP_LOGE(TAG, "Failed to connect to WiFi");
return ret;
}
ESP_LOGI(TAG, "WiFi connected successfully");
// Set passive receive mode (1) for better control
ret = set_rx_mode(t, 1);
if (ret != command_result::OK) {
ESP_LOGE(TAG, "Failed to set preferred Rx mode");
return ret;
}
return command_result::OK;
}
command_result net_close(CommandableIf *t)
{
ESP_LOGV(TAG, "%s", __func__);
// Disconnect from WiFi
auto ret = dce_commands::generic_command(t, "AT+CWQAP\r\n", "OK", "ERROR", 5000);
if (ret != command_result::OK) {
ESP_LOGW(TAG, "Failed to disconnect WiFi (may already be disconnected)");
}
return command_result::OK;
}
command_result tcp_open(CommandableIf *t, const std::string &host, int port, int timeout)
{
ESP_LOGV(TAG, "%s", __func__);
// Set single connection mode (just in case)
auto ret = dce_commands::generic_command(t, "AT+CIPMUX=0\r\n", "OK", "ERROR", 1000);
if (ret != command_result::OK) {
ESP_LOGW(TAG, "Failed to set single connection mode");
}
// Establish TCP connection
std::string tcp_cmd = "AT+CIPSTART=\"TCP\",\"" + host + "\"," + std::to_string(port) + "\r\n";
ret = dce_commands::generic_command(t, tcp_cmd, "CONNECT", "ERROR", timeout);
if (ret != command_result::OK) {
ESP_LOGE(TAG, "Failed to establish TCP connection to %s:%d", host.c_str(), port);
return ret;
}
ESP_LOGI(TAG, "TCP connection established to %s:%d", host.c_str(), port);
return command_result::OK;
}
command_result tcp_close(CommandableIf *t)
{
ESP_LOGV(TAG, "%s", __func__);
return dce_commands::generic_command(t, "AT+CIPCLOSE\r\n", "CLOSED", "ERROR", 5000);
}
command_result tcp_send(CommandableIf *t, uint8_t *data, size_t len)
{
ESP_LOGV(TAG, "%s", __func__);
// This function is not used in the current implementation
// Data sending is handled by the DCE responder
return command_result::FAIL;
}
command_result tcp_recv(CommandableIf *t, uint8_t *data, size_t len, size_t &out_len)
{
ESP_LOGV(TAG, "%s", __func__);
// This function is not used in the current implementation
// Data receiving is handled by the DCE responder
return command_result::FAIL;
}
command_result get_ip(CommandableIf *t, std::string &ip)
{
ESP_LOGV(TAG, "%s", __func__);
std::string out;
auto ret = dce_commands::at_raw(t, "AT+CIFSR\r\n", out, "OK", "ERROR", 5000);
if (ret != command_result::OK) {
return ret;
}
// Parse station IP from response
// Expected format: +CIFSR:STAIP,"192.168.1.100"
auto pos = out.find("+CIFSR:STAIP,\"");
if (pos != std::string::npos) {
pos += 14; // Move past "+CIFSR:STAIP,\""
auto end_pos = out.find("\"", pos);
if (end_pos != std::string::npos) {
ip = out.substr(pos, end_pos - pos);
ESP_LOGI(TAG, "Got IP address: %s", ip.c_str());
return command_result::OK;
}
}
ESP_LOGE(TAG, "Failed to parse IP address from response");
return command_result::FAIL;
}
command_result set_rx_mode(CommandableIf *t, int mode)
{
ESP_LOGE(TAG, "%s", __func__);
// Active mode (0) sends data automatically, Passive mode (1) notifies about data for reading
std::string cmd = "AT+CIPRECVTYPE=" + std::to_string(mode) + "\r\n";
return dce_commands::generic_command(t, cmd, "OK", "ERROR", 1000);
}
} // sock_commands
namespace sock_dce {
void Responder::start_sending(size_t len)
{
data_to_send = len;
send_stat = 0;
send_cmd("AT+CIPSEND=" + std::to_string(len) + "\r\n");
}
void Responder::start_receiving(size_t len)
{
send_cmd("AT+CIPRECVDATA=" + std::to_string(len) + "\r\n");
}
bool Responder::start_connecting(std::string host, int port)
{
std::string cmd = "AT+CIPSTART=\"TCP\",\"" + host + "\"," + std::to_string(port) + "\r\n";
send_cmd(cmd);
return true;
}
Responder::ret Responder::recv(uint8_t *data, size_t len)
{
const int MIN_MESSAGE = 6;
size_t actual_len = 0;
auto *recv_data = (char *)data;
if (data_to_recv == 0) {
const std::string_view head = "+CIPRECVDATA:";
// Find the response header
auto head_pos = std::search(recv_data, recv_data + len, head.data(), head.data() + head.size(), [](char a, char b) {
return a == b;
});
if (head_pos == recv_data + len) {
return ret::FAIL;
}
// Find the end of the length field
auto next_comma = (char *)memchr(head_pos + head.size(), ',', MIN_MESSAGE);
if (next_comma == nullptr) {
return ret::FAIL;
}
// Parse the actual length
if (std::from_chars(head_pos + head.size(), next_comma, actual_len).ec == std::errc::invalid_argument) {
ESP_LOGE(TAG, "Cannot convert length");
return ret::FAIL;
}
ESP_LOGD(TAG, "Received: actual len=%zu", actual_len);
if (actual_len == 0) {
ESP_LOGD(TAG, "No data received");
return ret::FAIL;
}
if (actual_len > buffer_size) {
ESP_LOGE(TAG, "Data too large: %zu > %zu", actual_len, buffer_size);
return ret::FAIL;
}
// Move to the actual data after the comma
recv_data = next_comma + 1;
auto first_data_len = len - (recv_data - (char *)data);
if (actual_len > first_data_len) {
on_read(recv_data, first_data_len);
data_to_recv = actual_len - first_data_len;
return ret::NEED_MORE_DATA;
}
on_read(recv_data, actual_len);
} else if (data_to_recv > len) { // Continue receiving
on_read(recv_data, len);
data_to_recv -= len;
return ret::NEED_MORE_DATA;
} else if (data_to_recv <= len) { // Last chunk
on_read(recv_data, data_to_recv);
actual_len = data_to_recv;
}
// Look for "OK" marker after the data
char *ok_pos = nullptr;
if (actual_len + 1 + 2 /* OK */ <= len) {
ok_pos = (char *)memchr(recv_data + actual_len + 1, 'O', MIN_MESSAGE);
if (ok_pos == nullptr || ok_pos[1] != 'K') {
data_to_recv = 0;
return ret::FAIL;
}
}
// Reset and prepare for next receive
data_to_recv = 0;
return ret::OK;
}
Responder::ret Responder::send(uint8_t *data, size_t len)
{
if (send_stat < 3) {
// Look for the '>' prompt
if (memchr(data, '>', len) == NULL) {
if (send_stat++ < 2) {
return ret::NEED_MORE_DATA;
}
ESP_LOGE(TAG, "Missed '>' prompt");
return ret::FAIL;
}
// Send the actual data
auto written = dte->write(&buffer[0], data_to_send);
if (written != data_to_send) {
ESP_LOGE(TAG, "Failed to write data: %d/%zu", written, data_to_send);
return ret::FAIL;
}
data_to_send = 0;
send_stat = 3;
}
return ret::IN_PROGRESS;
}
Responder::ret Responder::send(std::string_view response)
{
if (send_stat == 3) {
if (response.find("SEND OK") != std::string::npos) {
send_stat = 0;
return ret::OK;
} else if (response.find("SEND FAIL") != std::string::npos) {
ESP_LOGE(TAG, "Send failed");
return ret::FAIL;
} else if (response.find("ERROR") != std::string::npos) {
ESP_LOGE(TAG, "Send error");
return ret::FAIL;
}
}
return ret::IN_PROGRESS;
}
Responder::ret Responder::connect(std::string_view response)
{
if (response.find("CONNECT") != std::string::npos) {
ESP_LOGI(TAG, "TCP connected!");
return ret::OK;
}
if (response.find("ERROR") != std::string::npos) {
ESP_LOGE(TAG, "Failed to connect");
return ret::FAIL;
}
return ret::IN_PROGRESS;
}
Responder::ret Responder::check_async_replies(status state, std::string_view &response)
{
ESP_LOGD(TAG, "Response: %.*s", static_cast<int>(response.size()), response.data());
// Handle WiFi status messages
if (response.find("WIFI CONNECTED") != std::string::npos) {
ESP_LOGI(TAG, "WiFi connected");
} else if (response.find("WIFI DISCONNECTED") != std::string::npos) {
ESP_LOGW(TAG, "WiFi disconnected");
}
// Handle TCP status messages
if (response.find("CONNECT") != std::string::npos && state == status::CONNECTING) {
return connect(response);
} else if (response.find("CLOSED") != std::string::npos) {
ESP_LOGW(TAG, "TCP connection closed");
return ret::FAIL;
}
// Handle data notifications in active mode (if we switch to it later)
if (response.find("+IPD,") != std::string::npos) {
uint64_t data_ready = 1;
write(data_ready_fd, &data_ready, sizeof(data_ready));
ESP_LOGD(TAG, "Data available notification");
}
if (state == status::SENDING) {
return send(response);
} else if (state == status::CONNECTING) {
return connect(response);
}
return ret::IN_PROGRESS;
}
Responder::ret Responder::process_data(status state, uint8_t *data, size_t len)
{
if (state == status::SENDING) {
return send(data, len);
}
if (state == status::RECEIVING) {
return recv(data, len);
}
return ret::IN_PROGRESS;
}
status Responder::pending()
{
// For ESP-AT, we don't need a pending check like BG96
// Just return current status
return status::SENDING;
}
} // sock_dce

View File

@@ -0,0 +1,2 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_EXAMPLE_MODEM_DEVICE_ESPAT=y

View File

@@ -13,5 +13,5 @@ CONFIG_EXAMPLE_MODEM_PPP_APN="lpwa.vodafone.com"
CONFIG_EXAMPLE_MQTT_TEST_TOPIC="/ci/esp-modem/pppos-client"
CONFIG_EXAMPLE_PAUSE_NETIF_TO_CHECK_SIGNAL=y
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
CONFIG_ESP32_PANIC_PRINT_HALT=y
CONFIG_EXAMPLE_DETECT_MODE_BEFORE_CONNECT=y
CONFIG_EXAMPLE_MQTT_BROKER_URI="mqtt://${CI_MQTT_BROKER_URI}"

View File

@@ -8,7 +8,6 @@ CONFIG_LWIP_PPP_ENABLE_IPV6=n
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y
CONFIG_EXAMPLE_MODEM_DEVICE_A7670=y
CONFIG_EXAMPLE_MODEM_PPP_APN="lpwa.vodafone.com"
CONFIG_EXAMPLE_MODEM_PPP_AUTH_NONE=y
CONFIG_EXAMPLE_MQTT_TEST_TOPIC="/ci/esp-modem/pppos-client"
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
CONFIG_ESP32_PANIC_PRINT_HALT=y
CONFIG_EXAMPLE_MQTT_BROKER_URI="mqtt://${CI_MQTT_BROKER_URI}"

View File

@@ -11,9 +11,8 @@ CONFIG_EXAMPLE_MODEM_DEVICE_SIM800=y
CONFIG_EXAMPLE_MODEM_DEVICE_BG96=n
CONFIG_EXAMPLE_MODEM_PPP_APN="lpwa.vodafone.com"
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
CONFIG_ESP32_PANIC_PRINT_HALT=y
CONFIG_COMPILER_CXX_EXCEPTIONS=y
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
CONFIG_EXAMPLE_CLOSE_CMUX_AT_END=y
CONFIG_EXAMPLE_MQTT_TEST_TOPIC="/ci/esp-modem/pppos-client"
CONFIG_BROKER_URI="mqtt://test.mosquitto.org"
CONFIG_BROKER_URI="mqtt://${CI_MQTT_BROKER_URI}"

View File

@@ -62,12 +62,16 @@ class Creator {
public:
Creator(std::shared_ptr<DTE> dte, esp_netif_t *esp_netif): dte(std::move(dte)), device(nullptr), netif(esp_netif)
{
#ifdef CONFIG_ESP_MODEM_USE_PPP_MODE
ESP_MODEM_THROW_IF_FALSE(netif != nullptr, "Null netif");
#endif
}
Creator(std::shared_ptr<DTE> dte, esp_netif_t *esp_netif, std::shared_ptr<T_Module> dev): dte(std::move(dte)), device(std::move(dev)), netif(esp_netif)
{
#ifdef CONFIG_ESP_MODEM_USE_PPP_MODE
ESP_MODEM_THROW_IF_FALSE(netif != nullptr, "Null netif");
#endif
}
explicit Creator(std::shared_ptr<DTE> dte): dte(std::move(dte)), device(nullptr), netif(nullptr)

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,7 +14,6 @@
#include "cxx_include/esp_modem_dte.hpp"
#include "esp_netif_ppp.h"
namespace esp_modem {
void Netif::on_ppp_changed(void *arg, esp_event_base_t event_base,
@@ -39,6 +38,7 @@ esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len)
return ESP_FAIL;
}
#ifdef CONFIG_ESP_MODEM_USE_PPP_MODE
esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args)
{
auto d = (ppp_netif_driver *) args;
@@ -62,6 +62,7 @@ esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args)
return ESP_OK;
}
#endif // CONFIG_ESP_MODEM_USE_PPP_MODE
void Netif::receive(uint8_t *data, size_t len)
{
@@ -73,12 +74,16 @@ Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) :
{
driver.base.netif = ppp_netif;
driver.ppp = this;
#ifdef CONFIG_ESP_MODEM_USE_PPP_MODE
driver.base.post_attach = esp_modem_post_attach;
ESP_MODEM_THROW_IF_ERROR(esp_event_handler_register(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &on_ppp_changed, (void *) this));
#endif
ESP_MODEM_THROW_IF_ERROR(esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected, ppp_netif));
ESP_MODEM_THROW_IF_ERROR(
esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_LOST_IP, esp_netif_action_disconnected, ppp_netif));
#ifdef CONFIG_ESP_MODEM_USE_PPP_MODE
ESP_MODEM_THROW_IF_ERROR(esp_netif_attach(ppp_netif, &driver));
#endif
}
void Netif::start()
@@ -120,7 +125,9 @@ Netif::~Netif()
signal.clear(PPP_STARTED);
signal.wait(PPP_EXIT, 30000);
}
#ifdef CONFIG_ESP_MODEM_USE_PPP_MODE
esp_event_handler_unregister(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &on_ppp_changed);
#endif
esp_event_handler_unregister(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected);
esp_event_handler_unregister(IP_EVENT, IP_EVENT_PPP_LOST_IP, esp_netif_action_disconnected);
}

View File

@@ -14,11 +14,17 @@
#include "cxx_include/esp_modem_dte.hpp"
#include "esp_modem_config.h"
#include "cxx_include/esp_modem_api.hpp"
#include "esp_vfs_dev.h" // For optional VFS support
#include "vfs_resource/vfs_create.hpp"
#include "esp_idf_version.h"
#include "network_dce.hpp"
#include "manual_ota.hpp"
#include "mqtt_client.h"
// For optional VFS support
#include "vfs_resource/vfs_create.hpp"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
#include "driver/uart_vfs.h"
#else
#include "esp_vfs_dev.h"
#endif
using namespace esp_modem;
@@ -189,7 +195,12 @@ extern "C" void app_main(void)
assert(vfs_create_uart(&uart_config, &dte_config.vfs_config) == true);
auto dte = create_vfs_dte(&dte_config);
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
uart_vfs_dev_use_driver(uart_config.uart.port_num);
#else
esp_vfs_dev_uart_use_driver(uart_config.uart.port_num);
#endif
#else
auto dte = create_uart_dte(&dte_config);
#endif // CONFIG_TEST_USE_VFS_TERM

View File

@@ -64,6 +64,12 @@ static const char *TAG = "websocket_client";
#define WS_OVER_TCP_SCHEME "ws"
#define WS_OVER_TLS_SCHEME "wss"
#define WS_HTTP_BASIC_AUTH "Basic "
#define WS_HTTP_REDIRECT(code) ((code >= 300) && (code < 400))
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
// Features supported in 5.5.0
#define WS_TRANSPORT_REDIRECT_HEADER_SUPPORT 1
#endif
const static int STOPPED_BIT = BIT0;
const static int CLOSE_FRAME_SENT_BIT = BIT1; // Indicates that a close frame was sent by the client
@@ -1072,6 +1078,29 @@ static void esp_websocket_client_task(void *pv)
esp_websocket_client_abort_connection(client, WEBSOCKET_ERROR_TYPE_TCP_TRANSPORT);
break;
}
#if WS_TRANSPORT_REDIRECT_HEADER_SUPPORT
else if (WS_HTTP_REDIRECT(result)) {
const char *redir = esp_transport_ws_get_redir_uri(client->transport);
if (redir) {
// Redirecting to a new URI
free(client->config->uri);
client->config->uri = strdup(redir);
client->config->port = 0;
esp_websocket_client_set_uri(client, client->config->uri);
if (client->config->port == 0) {
client->config->port = esp_transport_get_default_port(client->transport);
}
// Rerun the connection with the redir uri.
client->state = WEBSOCKET_STATE_INIT;
ESP_LOGI(TAG, "Redirecting to %s", client->config->uri);
break;
}
}
#endif
ESP_LOGD(TAG, "Transport connected to %s://%s:%d", client->config->scheme, client->config->host, client->config->port);
client->state = WEBSOCKET_STATE_CONNECTED;

View File

@@ -1,8 +1,15 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS ../../esp_websocket_client
"$ENV{IDF_PATH}/tools/unit-test-app/components")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "6.0")
set(test_component_dir $ENV{IDF_PATH}/tools/test_apps/components)
else()
set(test_component_dir $ENV{IDF_PATH}/tools/unit-test-app/components)
endif()
set(EXTRA_COMPONENT_DIRS ../../esp_websocket_client
${test_component_dir})
project(websocket_unit_test)

View File

@@ -154,7 +154,7 @@
} \
}
#define queueFree(type, queue) while (queue) { type * _q = queue; queue = queue->next; free(_q); }
#define queueFree(type, queue) while (queue) { type * _q = queue; queue = queue->next; mdns_mem_free(_q); }
#define PCB_STATE_IS_PROBING(s) (s->state > PCB_OFF && s->state < PCB_ANNOUNCE_1)
#define PCB_STATE_IS_ANNOUNCING(s) (s->state > PCB_PROBE_3 && s->state < PCB_RUNNING)

View File

@@ -34,6 +34,7 @@ CFLAGS=-g -Wno-unused-value -Wno-missing-declarations -Wno-pointer-bool-conversi
-I$(COMPONENTS_DIR)/soc/src/esp32/include \
-I$(COMPONENTS_DIR)/xtensa/include \
-I$(COMPONENTS_DIR)/xtensa/esp32/include \
-I$(COMPONENTS_DIR)/esp_hw_support/etm/include \
-I$(COMPILER_ICLUDE_DIR)/include

View File

@@ -1,7 +1,15 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS ../.. "$ENV{IDF_PATH}/tools/unit-test-app/components")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "6.0")
set(test_component_dir $ENV{IDF_PATH}/tools/test_apps/components)
else()
set(test_component_dir $ENV{IDF_PATH}/tools/unit-test-app/components)
endif()
set(EXTRA_COMPONENT_DIRS ../..
${test_component_dir})
project(mdns_test)

View File

@@ -3,6 +3,6 @@ commitizen:
bump_message: 'bump(mosq): $current_version -> $new_version'
pre_bump_hooks: python ../../ci/changelog.py mosquitto
tag_format: mosq-v$version
version: 2.0.20~3
version: 2.0.20~4
version_files:
- idf_component.yml

View File

@@ -1,5 +1,17 @@
# Changelog
## [2.0.20~4](https://github.com/espressif/esp-protocols/commits/mosq-v2.0.20_4)
### Features
- Update brokerless example to work with esp-peer ([76e45f72](https://github.com/espressif/esp-protocols/commit/76e45f72))
### Bug Fixes
- drop newlib from PRIV_REQUIRES ([6318022c](https://github.com/espressif/esp-protocols/commit/6318022c))
- Make esp-peer build optional ([03df9ae9](https://github.com/espressif/esp-protocols/commit/03df9ae9))
- Fix esp_webRTC deprecation with new FreeRTOS ([78ae2559](https://github.com/espressif/esp-protocols/commit/78ae2559))
## [2.0.20~3](https://github.com/espressif/esp-protocols/commits/mosq-v2.0.20_3)

View File

@@ -82,7 +82,7 @@ idf_component_register(SRCS ${m_srcs}
${m_incl_dir} ${m_lib_dir} ${m_deps_dir}
INCLUDE_DIRS ${m_incl_dir} port/include
REQUIRES esp-tls
PRIV_REQUIRES newlib sock_utils esp_timer)
PRIV_REQUIRES sock_utils esp_timer)
target_compile_definitions(${COMPONENT_LIB} PRIVATE "WITH_BROKER")
if (CONFIG_MOSQ_ENABLE_SYS)

View File

@@ -1,3 +1,3 @@
idf_component_register(SRCS "example_broker.c"
PRIV_REQUIRES newlib nvs_flash esp_netif esp_event mqtt
PRIV_REQUIRES nvs_flash esp_netif esp_event mqtt
EMBED_TXTFILES servercert.pem serverkey.pem cacert.pem)

View File

@@ -0,0 +1,28 @@
From 600c9baaa622cd0885697829bcc5e22fa0a79e68 Mon Sep 17 00:00:00 2001
From: David Cermak <cermak@espressif.com>
Date: Fri, 25 Jul 2025 17:20:10 +0200
Subject: [PATCH] fix(media_lib): Remove deprecated API for get_stack_frame API
---
components/media_lib_sal/port/media_lib_os_freertos.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/components/media_lib_sal/port/media_lib_os_freertos.c b/components/media_lib_sal/port/media_lib_os_freertos.c
index d248d59..1117926 100644
--- a/components/media_lib_sal/port/media_lib_os_freertos.c
+++ b/components/media_lib_sal/port/media_lib_os_freertos.c
@@ -369,7 +369,11 @@ static int _get_stack_frame(void** addr, int n)
TaskSnapshot_t snap_shot;
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
vTaskGetSnapshot(cur_task, &snap_shot);
- snap_shot.pxTopOfStack = pxTaskGetStackStart(cur_task);;
+#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0))
+ snap_shot.pxTopOfStack = xTaskGetStackStart(cur_task);
+#else
+ snap_shot.pxTopOfStack = pxTaskGetStackStart(cur_task);
+#endif
esp_backtrace_get_start(&(frame.pc), &(frame.sp), &(frame.next_pc));
for (int i = 0; i < n; i++) {
--
2.43.0

View File

@@ -14,6 +14,7 @@ COMPONENTS_SRC="${EXTRACTED_DIR}/components"
COMPONENTS_DST="${ESP_PEER_DIR}/components"
PATCH_FILE_1="${THIS_DIR}/Remove-deprecated-freeRTOS-header.patch"
PATCH_FILE_2="${THIS_DIR}/libpeer-Add-direct-dependency-to-libsrtp.patch"
PATCH_FILE_3="${THIS_DIR}/Remove-deprecated-API-for-get_stack_fr.patch"
# Download if not exists
if [ ! -d "$EXTRACTED_DIR" ]; then
@@ -22,6 +23,7 @@ if [ ! -d "$EXTRACTED_DIR" ]; then
unzip -o "$ZIP_PATH" -d "$ESP_PEER_DIR"
patch -p1 -d "$EXTRACTED_DIR" < "$PATCH_FILE_1"
patch -p1 -d "$EXTRACTED_DIR" < "$PATCH_FILE_2"
patch -p1 -d "$EXTRACTED_DIR" < "$PATCH_FILE_3"
mv ${EXTRACTED_DIR}/components ${ESP_PEER_DIR}
mv ${ESP_PEER_DIR}/components/esp_webrtc/impl/peer_default ${ESP_PEER_DIR}/components
fi

View File

@@ -1,4 +1,4 @@
version: "2.0.20~3"
version: "2.0.20~4"
url: https://github.com/espressif/esp-protocols/tree/master/components/mosquitto
description: The component provides a simple ESP32 port of mosquitto broker
dependencies:

View File

@@ -20,4 +20,4 @@
#undef isspace
#define isspace(__c) (__ctype_lookup((int)__c)&_S)
#define VERSION "v2.0.20~3"
#define VERSION "v2.0.20~4"

View File

@@ -0,0 +1,2 @@
# CONFIG_ESP_EVENT_POST_FROM_ISR is not set
CONFIG_BROKER_URL="mqtt://${CI_MQTT_BROKER_URI}"